美文网首页
WPF:Window.Dispatcher调度的代码滞后执行的问

WPF:Window.Dispatcher调度的代码滞后执行的问

作者: hhp895 | 来源:发表于2019-02-15 16:22 被阅读0次

    问题描述

    在实现一个子线程进行网络文件下载,需要记录下载文件队列完成进度,以及每个文件下载进度。子线程中下载每一个文件是一个阻塞代码,也就是代码是在一个线程中往下执行,下载过程中需要向UI更新当前文件下载进度,使用进度条A表示,下载完毕后,要更新下载多个文件队列的进度,使用进度条B表示。
    假设当前有3个文件需要下载,第一个文件下载完毕,进度条B就需要更新到1/3位置,进度条的更新代码是依靠Window.Dispatcher来执行的。

     this.Dispatcher.BeginInvoke(new Action(() => {
          //ui更新代码写在这里
     }));
    

    整体代码结构如下:

    new Thread(()=>{
    for(int i=0;i<list.Count;i++)//list为下载队列
    {  
        //下载....
        // ....
        //下载完毕
         this.Dispatcher.BeginInvoke(new Action(() => {
            //ui更新代码写在这里
            progressBar.value=i*1.0/list.Count*100;//问题:i总是不从0开始,而是从1开始,滞后一个
         }));
    }
    list.clear();
    }).start();
    

    分析

    经过变量i的跟踪:

    new Thread(()=>{
    for(int i=0;i<list.Count;i++)//list为下载队列
    {  
        //下载....
        // ....
        //下载完毕
        Console.WriteLine("i={0},list.Count={1}", i, list.Count);
         this.Dispatcher.BeginInvoke(new Action(() => {
            //ui更新代码写在这里
            Console.WriteLine("Dispatcher:i={0},list.Count={1}",i, list.Count);
            progressBar.value=i*1.0/list.Count*100;//问题:i总是不从0开始,而是从1开始,滞后一个
         }));
    }
    list.clear();
    }).start();
    

    发现日志输出:

    i=0,list.Count=3
    Dispatcher:i=1,list.Count=3
    i=1,list.Count=3
    Dispatcher:i=2,list.Count=3
    i=2,list.Count=3
    Dispatcher:i=1,list.Count=0
    

    总是滞后于子线程执行。

    解决

    new Thread(()=>{
    for(int i=0;i<list.Count;i++)//list为下载队列
    {  
        //下载....
        // ....
        //下载完毕,更新进度
        int j=i;//复制一份i的值到j中,即使i变更了,也暂时不影响j
        int count=list.Count;
       //因为Dispatcher调度后的代码执行,不马上立即执行,会滞后,当执行调度后的代码时,i和list.Count的值已经发生了变化。
        Console.WriteLine("j={0},count={1}", j, count);
         this.Dispatcher.BeginInvoke(new Action(() => {
            //ui更新代码写在这里
            Console.WriteLine("Dispatcher:j={0},count={1}",j, count);
            progressBar.value=j*1.0/count*100;//问题:滞后执行,值变量赋值后得以解决。
         }));
    }
    list.Clear();
    }).start();
    

    日志输出:

    j=0,count=3
    Dispatcher:j=0,count=3
    j=1,count=3
    Dispatcher:j=1,count=3
    j=2,count=3
    Dispatcher:j=2,count=3
    

    相关文章

      网友评论

          本文标题:WPF:Window.Dispatcher调度的代码滞后执行的问

          本文链接:https://www.haomeiwen.com/subject/byfmeqtx.html