wpf研究之道-ProgressBar(进度条)控件

C#

浏览数:62

2019-9-18

AD:资源代下载服务

     ProgressBar控件,非常有用。它在什么情况下有用呢?如何使用?带着这两个问题,我们探讨下。

    如果程序需要很长时间来运行,用户在不知道的情况下,以为程序已经“卡死”了,没有响应,这时候就该用进度条了,它主动告诉用户的执行情况,那么用户知道还需要等待多久。

    上面的使用场景,很好理解,那么,如何使用呢?

    一边要执行长任务,一边还要不断地显示当前进度。这时候就得用多线程了,有人说那我就用单线程怎么了,那么咱们试一试便知道了。看如下的代码:

 1    private void progressTest_Click(object sender, RoutedEventArgs e)
 2         {
 3             this.myBar.Minimum = 0;
 4             this.myBar.Maximum = 1;
 5             Computer();
 6 
 7         }
 8 
 9         private void Computer()
10         {
11             for (int i = 1; i <= 100; i++)
12             {
13                 var num = i;
14 
15                 this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
16                            (ThreadStart)delegate()
17                            {
18                                this.myBar.Value = num / (double)100;
19 
20                            });
21 
22                 Thread.Sleep(100);
23             }
24         }

我们模拟了一个小循环,里面耗费一些时间,运行的过程,一直是这样的:

等程序运行完成后的结果:

换句话说,我们的进度条多此一举,没有起到进度变化的效果。我把程序改成多线程的:

 1  private void progressTest_Click(object sender, RoutedEventArgs e)
 2         {
 3             this.myBar.Minimum = 0;
 4             this.myBar.Maximum = 1;
 5 
 6 
 7             Thread t = new Thread(() =>
 8             {
 9                 Computer();
10             });
11             t.Start();
12 
13         }
14 
15         private void Computer()
16         {
17             for (int i = 1; i <= 100; i++)
18             {
19                 var num = i;
20 
21                 this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
22                            (ThreadStart)delegate()
23                            {
24                                this.myBar.Value = num / (double)100;
25 
26                            });
27 
28                 Thread.Sleep(100);
29             }
30         }

运行图如下:

为什么会出现这种情况?

       一个人专心致志地做某件事情,如果中途不停地有人来打扰,是不是事情就没法做了呢。同理,如果当前的线程正在跑大任务,还要不停地刷新进度条。这个是不是很浪费执行的效率?所以我觉得从设计的角度理解,不允许单线程这样做。从第一组图中,就可以看出,单线程专心致志地做完事情后,才去更新界面。

      公交车司机一边开车,到了某一站后,也不是亲自报站,而报站的任务落在了售票员身上,如果无售票员,那么司机按下系统按钮,让公交车上的报站设备去报。程序中往往运行大任务的是新开的另一个线程,此时主线程负责刷新界面,即刷新进度。

 

作者:micDavid