BackgroundWorker 组件使用

.Net技术 码拜 10年前 (2014-11-06) 3292次浏览 0个评论

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

若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。 可以通过编程方式创建 BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。 如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。

若要为后台操作做好准备,请添加 DoWork 事件的事件处理程序。 在此事件处理程序中调用耗时的操作。 若要开始此操作,请调用 RunWorkerAsync。 若要收到进度更新的通知,请处理 ProgressChanged 事件。 若要在操作完成时收到通知,请处理 RunWorkerCompleted 事件。

下面指出BackgroundWorker类的常用属性和事件。

重要属性:

CancellationPending——只读,指示应用程序是否已请求取消后台操作。若为真则退出线程。

IsBusy——只读,指示 BackgroundWorker 是否正在运行异步操作

WorkerReportsProgress——读写,该值指示 BackgroundWorker 能否报告进度更新。若为false,   调用ReportProgress方法时会抛出异常

WorkerSupportsCancellation——读写,该值指示 BackgroundWorker 是否支持异步取消。若为false则在取消同步方法CancelAsync时引发InvalidOperationException 异常

//

重要事件:
DoWork——调用 RunWorkerAsync 时发生。

ProgressChanged——调用 ReportProgress 时发生。

RunWorkerCompleted——当后台操作已完成、被取消或引发异常时发生。
重要方法:
CancelAsync——请求取消挂起的后台操作

ReportProgress(Int32,Object)——引发 ProgressChanged 事件

RunWorkerAsync——开始执行后台操作

BackgroundWorker的使用非常简单,从工具箱中拖出即可(当然也可以自己用代码声明一个BackgroundWorker对象)。其使用流程包括三个:

1)DoWork,顾名思义,这个事件里主要进行后台操作,不应设计UI交互

2)ProgressChanged,后台线程的工作有了一定进展的时候,就可以在这里反馈给UI界面显示,这个方法运行于主线程内。

3)RunWorkerCompleted,调用结束后的相关操作。这个方法也位于主线程内。调用结束有三种情况:完成任务、异常退出、取消任务。

具备了以上三部分内容以后,只要适时调用BackgroundWorker的RunWorkerAsync,就会触发DoWork事件开辟后台线程处理数据;而在DoWork中调用ReportProgress报告处理进度时又会触发ProgressChanged事件,可以与UI进行交互。当调用后台线程处理完成或调用CancelAsync方法或发生错误时,又会触发RunWorkerCompleted事件。这样完成了整个流程。

接下来通过一段代码示例说明BackgroundWorker的工作流程

示例代码:

namespace backgroundWorkerTest

{

public partial class Form1 : Form

{

//声明一个BackgroundWorker类的示例,也可以从工具箱中拖动一个BackgroundWorker组件到设计界面

//如果是自己声明的话,则需要重载对应的方法,或为BackgroundWorker对应的事件绑定委托链

//private BackgroundWorker worker = new BackgroundWorker();

public Form1()

{

InitializeComponent();

//要求worker能报告进度更新,否则调用ReportProgress方法时会抛出异常:此 BackgroundWorker 声明它不报告进度。请修改 WorkerReportsProgress 以声明它报告进度。

backgroundWorker1.WorkerReportsProgress = true;

//要求worker支持异步取消,否则在取消同步方法CancelAsync时引发InvalidOperationException 异常

backgroundWorker1.WorkerSupportsCancellation = true;

}

 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

{

/// <summary>

/// DoWork方法将会在BackgroundWorker创建的一个后台线程中运行

/// 所以这里面不要涉及UI操作;也不用使用try catch块,BackgroundWorker能自动探测相关异常

/// </summary>

e.Result = ListNumber(backgroundWorker1, e);

}

 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)

{

/// 这个方法对应的事件运行于主线程内

/// 可以在这里进行UI操作

 

//显示完成进度

progressBar1.Value = e.ProgressPercentage;

label2.Text = e.ProgressPercentage + “%”;

//列出数字

listBox1.Items.Add(e.UserState.ToString());

}

 

Private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

{

///结束任务时调用,结束任务的情况包括:1)完成操作2)异常错误3)取消操作

 

MessageBox.Show(“完成!”);

}

private int ListNumber(object sender, DoWorkEventArgs e)

{

for (int i = 0; i < 1000; i++)

{

if (backgroundWorker1.CancellationPending)//如果已请求取消后台操作,退出

{

e.Cancel = true;

return -1;

}

else

{

System.Threading.Thread.Sleep(1);//交出时间片(很重要,没有这一句会造成死锁)

int percent = i / 10;//计算已完成的百分比

///报告完成进度,引发 ProgressChanged 事件,两种重载形式

///ReportProgress(int percentProcess)

///ReportProgress(int percentProcess,object userState)

///percentProcess为完成进度的百分数,必须为[0,100]间的整数,否则抛出异常

///userState传递到RunWorkerAsync 的状态对象

backgroundWorker1.ReportProgress(percent, i);

}

}

return -1;

}

//开始

private void btnStart_Click(object sender, EventArgs e)

{

if (backgroundWorker1.IsBusy != true)

{

//开始同步操作

backgroundWorker1.RunWorkerAsync();

}

}

//暂停

private void btnPause_Click(object sender, EventArgs e)

{

if (backgroundWorker1.WorkerSupportsCancellation == true)

{

//取消同步操作

backgroundWorker1.CancelAsync();

}

}

}

}


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明BackgroundWorker 组件使用
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!