BackgroundWorker 类

转自:http://blog.csdn.net/zhongjiekangping/article/details/4563357(代码做了修改,原文中代码冗长)

特点:

BackgroundWorker 类允许在单独的专用线程上运行操作。

用途:

耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。

若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度,并在操作完成时发出信号的事件

创建:

(1) 可以通过编程方式创建BackgroundWorker

(2) 可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。

使用:

(1) 若要设置后台操作,请为 DoWork事件添加一个事件处理程序;

在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync();

(2) 若要收到进度更新通知,请对 ProgressChanged事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。

注意:

您必须非常小心,确保在 DoWork事件处理程序中不操作任何用户界面对象;而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信

BackgroundWorker 事件不跨 AppDomain 边界进行封送处理。请不要使用 BackgroundWorker 组件在多个 AppDomain 中执行多线程操作。

补充:

AppDomain类,表示应用程序域,它是一个应用程序在其中执行的独立环境。 此类不能被继承。

(3) 如果后台操作需要参数,请在调用 RunWorkerAsync() 时给出参数;在 DoWork事件处理程序内部,可以从 DoWorkEventArgs.Argument 属性中提取该参数。

有关 BackgroundWorker 的更多信息,请参见 如何:在后台运行操作。

注意:

应用于此类的 HostProtectionAttribute 属性 (Attribute) 具有以下 Resources 属性 (Property) 值: SharedState。

HostProtectionAttribute 不影响桌面应用程序(这些应用程序通常通过双击图标、键入命令或在浏览器中输入 URL 来启动)。

有关更多信息,请参见 HostProtectionAttribute 类或 SQL Server 编程和宿主保护属性。

BackgroundWorker类中主要用到的属性、方法和事件:

重要属性:

1、CancellationPending:获取一个值,指示应用程序是否已请求取消后台操作。

通过在DoWork事件中判断CancellationPending属性可以认定是否需要取消后台操作(也就是结束线程);

2、IsBusy:获取一个值,指示 BackgroundWorker 是否正在运行异步操作。

程序中使用IsBusy属性用来确定后台操作是否正在使用中;

3、WorkerReportsProgress:获取或设置一个值,该值指示BackgroundWorker能否报告进度更新

4、WorkerSupportsCancellation:获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消

设置WorkerSupportsCancellation为true,使得程序可以调用CancelAsync方法提交终止挂起的后台操作的请求;

 重要方法:

1、CancelAsync:请求取消挂起的后台操作

2、RunWorkerAsync:开始执行后台操作

3、ReportProgress:引发ProgressChanged事件  

重要事件(仅有的三个事件):

1、DoWork:调用 RunWorkerAsync 时发生

2、ProgressChanged:调用 ReportProgress 时发生

3、RunWorkerCompleted:当后台操作已完成、被取消或引发异常时发生

重要的参数(仅有的三个参数):

1、RunWorkerCompletedEventArgs(RunWorkerCompleted事件的参数)

主要的有三个属性:

1> Error 指示异步操作期间发生的错误

2>Cancelled 指示异步操作是否被取消

3> Result 获取异步操作的结果

2、DoWorkEventArgs(DoWork事件的参数)

最主要的是其Result属性,该属性存储计算的结果(Object类型),但须注意,该结果不能与UI进行交互

3、ProgressChangedEventArgs(ProgressChanged事件的参数)

最主要的是其ProgressPercentage属性,该属性可以反映后台工作的进展情况

BackgroundWorker的各属性、方法、事件的调用机制和顺序:


从上图可见,在整个生命周期内发生了3次重要的参数传递过程

参数传递1(传入参数):此次的参数传递是将RunWorkerAsync(Object)中的Object传递到DoWork事件的DoWorkEventArgs.Argument

由于在这里只有一个参数可以传递,所以在实际应用时,常封装一个类,将整个实例化的类作为RunWorkerAsync的Object传递到DoWorkEventArgs.Argument;

参数传递2(后台程序进度):此次是将程序运行进度传递给ProgressChanged事件,实际使用中往往使用给方法和事件更新进度条或者日志信息;

参数传递3(运行结果):在DoWork事件结束之前,将后台线程产生的结果数据赋给DoWorkEventArgs.Result,以便在RunWorkerCompleted事件中调用RunWorkerCompletedEventArgs.Result属性取得后台线程产生的结果。

另外从上图可以看到DoWork事件是在后台线程中运行的,所以在该事件中不能够操作用户界面的内容,如果需要更新用户界面,可以使用ProgressChanged事件及RunWorkCompleted事件来实现。

实例:

下面的代码示例演示如何使用 BackgroundWorker 类异步执行耗时的操作。该操作计算选定的斐波纳契数,在计算过程中报告进度更新,并允许取消挂起的计算。

用户界面如下:

增加了组件:BackGroundWork


成员变量:

       //需要计算的Fibonacci
        private int m_calcNum;
        //计算进度
        private int m_highestProcess;

Fibonacci的计算:

        //递归计算Fibonacci数值
        long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e)
        {
            // The parameter n must be >= 0 and <= 91.  
            // Fib(n), with n > 91, overflows a long.
            //输入出错的话,抛出错误
            if ((n < 0) || (n > 91))
            {
                throw new ArgumentException("value must be >= 0 and <= 91", "n");
            }

            long result = 0; 

            //检查应用程序是否已经取消了后台操作
            if (worker.CancellationPending)
            {
                e.Cancel = true;
                return 0;
            }
            
            //递归计算
            if (n < 2)
            {
                result = 1;
            }
            else
            {
                result = ComputeFibonacci(n - 1, worker, e) + ComputeFibonacci(n - 2, worker, e);
            }

            // 任务进度的计算
            int percentComplete =(int)((float)n / (float)m_calcNum * 100);

            if (percentComplete > m_highestProcess)
            {
                m_highestProcess = percentComplete;
                //报告计算进度
                worker.ReportProgress(percentComplete);
            }

            return result;
        }  
开始计算按钮:

        //开始计算
        private void calcBtn_Click(object sender, EventArgs e)
        {
            //计算进度设为0
            m_highestProcess = 0;
            //获取需要计算的Fibonacci数值
            m_calcNum = int.Parse(CalcTextBox.Text);
            //开始异步执行后台程序
            CalcBackgroundWorker.RunWorkerAsync(m_calcNum);  
        }
取消计算按钮:

        //取消计算
        private void cancelBtn_Click(object sender, EventArgs e)
        {
            //取消挂起的后台操作??
            CalcBackgroundWorker.CancelAsync();
        }
组件的DoWork事件响应:

        //组件的DoWork事件
        //被RunWorkerAsync()调用
        private void CalcBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get the BackgroundWorker that raised this event.  
            BackgroundWorker worker = sender as BackgroundWorker;

            //执行计算,并将结果存储在e.Result中
            e.Result = ComputeFibonacci((int)e.Argument, worker, e);
        }
组件的ProgressChanged事件:

        //组件的ProgressChanged事件
        private void CalcBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            CalProgressBar.Value = e.ProgressPercentage;
        }
组件的RunWorkerCompleted事件:

        //组件的RunWorkerCompleted事件,进行计算结束之后的处理
        private void CalcBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // First, handle the case where an exception was thrown.  
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                //for test
                Console.WriteLine("操作已取消");
            }
            else
            {
                // Finally, handle the case where the operation succeeded.
                ResultTextBox.Text = e.Result.ToString();
            }
        }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值