您现在的位置: 365建站网 > 365学习 > C#中BackGroundWorker多线程时时刷新UI界面,并显示进度的用法

C#中BackGroundWorker多线程时时刷新UI界面,并显示进度的用法

文章来源:365jz.com     点击数:409    更新时间:2018-06-10 10:53   参与评论

凡是WinForm的应用程序,如果他执行了一个的非常冗长的处理操作(比如文件查询),它在执行时会锁定用户界面,虽然主活动窗口 一直在运行,但用户无法与程序交互,无法移动窗体或改变窗体大小,所以用户感觉很不爽。如何做才能使得这个程序有响应。答案就是在后台线程中执行这个操作。
    在这里已经有了多种方法来做这个事情:
    (一)委托异步调用
将具体耗时的操作作为一个委托,并用BeginInvoke来异步执行这个委托(Invoke是同步调用),并且可以为这个操作传入参数并且通过EndInvoke方法获得返回返回值。
    (二)使用ThreadPool
新建.net FrameWork中自带的WaitCallback委托,然后放到线程池中运行ThreadPool.QueueUserWorkItem( callback ); 根据WaitCallback委托的定义,可以传入一个object类型的参数。
但是不能精确的控制线程池中的线程。
    (三)使用Thread
        和ThreadPool相比,使用Thread的开销会比较大。但是它有它的优势,使用 Thread 类可以显式管理线程。只要有可能,就应该使用 ThreadPool 类来创建线程。然而,在一些情况下,您还是需要创建并管理您自己的线程,而不是使用 ThreadPool 类。在.net 2.0 中,提供了一个新的委托 ParameterizedThreadStart 支持启动一个线程并传入参数,这是对原来的ThreadStart委托的改进。

    说了这么多还没有说到今天的主角BackgroundWorker,他也是一个在2.0中新增的类,可以用于启动后台线程,并在后台计算结束后调用主线程的方法.可以看出同样的功能使用委托的异步调用也可以实现,只是使用BackgroundWorker的话会更加的简便快捷,可以节省开发时间,并把你从创建自己的委托以及对它们的调用中解救出来。真是这样的吗看看下面这个例子。其实我也是从101Samples中看到的例子。
    先看看BackgroundWorker中的主要概念。

BackGroundWorker是微软提供的封装好了的,非常实用的控件,我们可以在控件中将其拖到Winform之中,然后简单的系统生成代码式的编辑事件处理。

以下是,比较经典且简单的实用,后面的一篇较复杂,不使用微软控件式,自行生成,并传递参数给多线程,并通过多线程更新主线程的多处UI,线程没操作完一笔记录,则报告进度,更新UI。

 

下图是微软提供给我们的控件,拖到Winform中

 

我们可以看到有如下三个事件:

1、线程执行的动作,一般用于复杂操作,DoWork

2、线程进度改变,进度条变化

3、线程执行完,这时候,又回到主线程执行了,可以访问主线程中的UI,操作主线程的UI

 

下列是最基本的核心代码,只给出最核心部分,其他简单部分省略。

 

如果我主线程要传递参数,以及多线程如何接受参数,可以参考多线程按F12去查看微软给出的操作,一般较多的是DataTable类型的,这个也是最常用的,可以参考笔者之前的关于多线程的一些比较实用的文章。


  1. private void buttonTest_Click(object sender, EventArgs e)  
           {  
               BackgroundWorker worker = new BackgroundWorker();  
               worker.WorkerReportsProgress = true;  
               worker.DoWork += Bw_DoWork;  
               worker.ProgressChanged += Bw_ProgressChanged;  
               worker.RunWorkerAsync();  
           }  
      
           private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)  
           {  
               labelProcess.Text = e.ProgressPercentage.ToString();  
           }  
      
           private void Bw_DoWork(object sender, DoWorkEventArgs e)  
           {  
               var worker = sender as BackgroundWorker;  
               for (int i = 0; i < 100; i++)  
               {  
                   worker.ReportProgress(i);  
                   Thread.Sleep(100);  
               }  
           }

结果如下图




如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (409人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------