享受代码,享受人生

SOA is an integration solution. SOA is message oriented first.
The Key character of SOA is loosely coupled. SOA is enriched
by creating composite apps.
posts - 207, comments - 2333, trackbacks - 152, articles - 44
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

BackgroudWorker 范例

Posted on 2005-08-18 16:15 idior 阅读(5079) 评论(9)  编辑 收藏 网摘 所属分类: Windbey
     在很多场合下, 你需要在主(UI)线程中运行一些比较耗时间的任务,比如以下的任务

l         Image downloads

l         Web service invocations

l         File downloads and uploads (including for peer-to-peer applications)

l         Complex local computations

l         Database transactions

l         Local disk access, given its slow speed relative to memory access

这个时候UI就会陷入一种假死的状态,会给用户带来一种很不好的体验. 如何在这里发挥多线程的优势以改善用户体验? .Net2.0System.ComponentModel.BackgroundWorker为我们提供了一个很方便的解决方法.

vs.net2005 101 sample中提供了一个计算素数的例子, 不过那个例子并没有全面演示BackgroundWorker的能力, 尤其是没有对线程工作过程(ReportProgress)中的能力做比较好的演示.因此我重新做了一个Demo.

            
   
    这个例子很简单
, 就是将左边列表中的内容移至的右边, 用一个进度条来显示移动的进度, 当然既然是BackgroundWorker这个时候主界面可以进行其他操作. 

       本文的源代码提供下载, 其中有详细注释, 所以我在此简要介绍一下需要注意的地方.

       BackgroundWorker主要通过对DoWork  ProgressChanged  RunWorkerCompleted三个事件的处理来完成任务. 需要注意在DoWork中不能直接操作主界面的元素.比如你在MainForm类中启动了一个BackgroundWorker, DoWork的处理方法中不能直接调用任何MainForm中的成员变量. 但是在ProgressChanged RunWorkerCompleted的事件处理中则无此限制, 可以在后台线程中直接调用主线程中的元素, 这是BackgroundWorker中最有亮点的地方. 虽然在DoWork的处理方法中不能调用但是它也提供了参数传递的方法,可以间接调用.示例如下:

   27     //If your background operation requires a parameter,

   28     //call System.ComponentModel.BackgroundWorker.RunWorkerAsync

   29     //with your parameter. Inside the System.ComponentModel.BackgroundWorker.DoWork

   30     //event handler, you can extract the parameter from the

   31     //System.ComponentModel.DoWorkEventArgs.Argument property.

   32     worker.RunWorkerAsync(leftList);

   27      private void worker_DoWork(object sender, DoWorkEventArgs e)

   28         {

   29             MoveList((BackgroundWorker)sender,e);

   30         }

   31 

   32         private void MoveList(BackgroundWorker worker,DoWorkEventArgs e)

   33         {  //get leftList in Main UI Thread from arguments

   34             IList<string> list = e.Argument as IList<string>;

   35             //...

   36         } 

而在ProgressChangedRunWorkerCompleted事件的处理方法中则更加简单.

   27         private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)

   28         {

   29             //Add string to the right listBox, we use rightList in Main UI Thread directly

   30             rightList.Add(e.UserState as string); 

   31         }

上述原则可以说是BackgroundWorker最需要注意的地方.

另外一个容易被人粗心漏过的地方是有关属性的设置.

如果你要使BackgroundWorker支持进度汇报和取消功能别忘了在初始化的时候为下面两个属性赋值.

// Specify that the background worker provides progress notifications           

          worker.WorkerReportsProgress = true;

          // Specify that the background worker supports cancellation

          worker.WorkerSupportsCancellation = true;

其它部分就让大家自己看代码吧.

BackgroundWorker内部实现是基于delegate的异步调用.
    
                                                       
源代码下载

Feedback

#1楼    回复  引用  查看    

2005-08-19 13:46 by 蛙蛙池塘      
就是进度条吧,呵呵

#2楼    回复  引用  查看    

2005-08-19 13:48 by 蛙蛙池塘      
FT,注释也用英文D,

#3楼 [楼主]   回复  引用  查看    

2005-08-19 15:02 by idior      
没错就是进度条, 特点就是这个进度条是异步的(在后台运行), 并且进度的显示是真实的. 英文大家就将就吧. :P

#4楼    回复  引用  查看    

2005-09-27 11:51 by 疾风      
我发现idior的文章总是很棒,呵呵

#5楼 [楼主]   回复  引用  查看    

2005-09-27 22:20 by idior      
谢谢鼓励:)

#6楼    回复  引用    

2005-12-06 17:18 by xing006 [未注册用户]
http://blog.csdn.net/xing2002/

BackgroundWorker(sourcecode for vs2003)

#7楼    回复  引用  查看    

2006-04-17 10:38 by 九头龙      
这个东东真的是不好用,有Bug,我的一个程序用了它,一天内收发数据一点问题也没有,大约25个小时以后,突然出了错说不在创建XXX控件的线程访问它,真是莫名其妙,我是在ProgressChanged事件函数里访问的某个UI控件,同样的代码防问了一天都没问题,怎么突然会出错了。这个东东很不稳定,有是线程是错的。不信你可以用System.IO.Port里的seriarport类和它一起用来收串口数据,怎么做都会出现"不在创建XXX控件的线程访问它"这条错误

#8楼    回复  引用    

2007-05-16 19:45 by huang [未注册用户]
在form.load事件中加上这句话就好了
Control.CheckForIllegalCrossThreadCalls = false;

#9楼    回复  引用    

2007-08-01 11:44 by seek [未注册用户]
代码中有段不怎么明白,
worker.RunWorkerAsync(leftList);
这个为什么要异步调用leftList??
我把这句屏蔽了之后 发现复制不成了,您能详细讲解下这个过程么?




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-08-18 16:37 编辑过
Google站内搜索
[推荐职位]上海盛大网络招聘架构师

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》

相关文章:

相关链接: