• BackgroudWorker 范例


         在很多场合下, 你需要在主(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的异步调用.
        
                                                           
    源代码下载

  • 相关阅读:
    CSP-S 2019游记
    南校五天集训游记
    web.xml模板
    JDBC Template的基本使用
    Spring AOP(3)使用AspectJ xml配置
    Spring AOP(2)使用AspectJ注解
    Spring Aop(面向切面编程)
    Spring Bean管理3(xml与注解混合使用)
    Python核心技术与实战——十二|Python的比较与拷贝
    test
  • 原文地址:https://www.cnblogs.com/idior/p/217796.html
Copyright © 2020-2023  润新知