摘要:介绍BackgroundWorker组件的功能及在基于事件的异步操作编程中的应用,并对组件的实现原理进行简述。
RunWorkerAsync启动异步操作
BackgroundWorker类的第1个主要方法是RunWorkerAsync,该方法提交一个以异步方式启动运行操作的请求,发出请求后,将引发 DoWork 事件,在事件处理程序中开始执行异步操作代码。RunWorkerAsync
方法签名如下:
public void RunWorkerAsync();
public void RunWorkerAsync(Object argument);如果异步操作需要操作参数,可以将其作为argument参数提供,由于参数类型为Object,因此访问时可能需要进行类型转换。
CancelAsync取消异步操作
CancelAsync 方法提交终止异步操作的请求,并将 CancellationPending 属性设置为 true。需要注意的是,CancelAsync 方法是否调用成功,同WorkerSupportsCancellation 属性相关,如果允许取消执行的异步操作,需将WorkerSupportsCancellation 属性设置为true,否则调用该方法将抛出异常。CancelAsync方法不含参数,方法签名如下:
public void CancelAsync(); 调用 CancelAsync 方法时,BackgroundWorker的 CancellationPending 属性值将被设置为true,因此在编写单独线程中执行的辅助方法时,代码中应定期检查 CancellationPending 属性,查看是否已将该属性设置为 true,如果为true,应该结束辅助方法的执行。
// 取消
if (bgw.CancellationPending)
{
e.Cancel = true;
break;
} 有一点需要注意的是,DoWork 事件处理程序中的代码有可能在发出取消请求时已经完成处理工作,因此,DoWork事件处理程序或辅助方法可能会错过设置CancellationPending属性为true的时机。在这种情况下,即使调用 CancelAsync方法发出了取消异步操作请求,RunWorkerCompleted 事件处理程序中RunWorkerCompletedEventArgs 参数的 Cancelled 标志也不会被设置为 true,这是在多线程编程中经常会出现的竞争条件问题,因此编写代码的时候需要考虑。
ReportProgress报告进度
在执行异步操作时,如果需要跟踪异步操作执行进度,BackgroundWorker类提供了
ReportProgress 方法,调用该方法将引发 ProgressChanged 事件,通过注册该事件在事件处理程序中获取异步执行进度信息。方法签名如下:
public void ReportProgress(int percentProgress);
public void ReportProgress(int percentProgress,Object userState);
IsBusy运行状态
IsBusy运行状态,签名如下:
publicbool IsBusy { get; }通过该属性查询BackgroundWorker实例是否正在运行异步操作,如果 BackgroundWorker 正在运行异步操作,则为true,否则为false。BackgroundWorker类的3个事件
DoWork事件处理程序用来调用辅助方法进行实际处理操作,由于该事件处理程序在不同于UI的线程上执行,因此需要确保在 DoWork 事件处理程序中不操作任何用户界面对象。如果辅助方法需要参数支持,可以通过RunWorkerAsync方法传入,在 DoWork 事件处理程序中,通过 DoWorkEventArgs.Argument 属性提取该参数。
在异步操作期间,可以通过 ProgressChanged事件处理程序获取异步操作进度信息,通过RunWorkerCompleted 事件处理程序获取异步操作结果信息,在ProgressChanged和RunWorkerCompleted的事件处理程序中可以安全的同用户界面进行通信。

BackgroundWorker bgw = new BackgroundWorker();
public A()
{
bgw.WorkerSupportsCancellation = true;
bgw.WorkerReportsProgress = true;
bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork); bgw.RunWorkerAsync();}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
//
for (int i = 0; i < 100; i++)
{
// 取消
if (bgw.CancellationPending)
{
e.Cancel = true;
break;
}
bgw.ReportProgress(i + 1);
}
}
ProgressChanged进度改变
void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// 更新进度条
this.progressBar1.Value = e.ProgressPercentage;
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// 跳转至结束页面
// 取消
if (e.Cancelled)
{
// 询问是否取消
}
// 报错
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
// 正常完成后的处理
}
本文详细介绍了BackgroundWorker组件在.NET框架中的应用,包括其主要成员介绍、实现原理以及在基于事件的异步操作编程中的使用方法。重点讨论了如何利用该组件在单独的线程上执行耗时操作,同时保证用户界面的响应性。
499

被折叠的 条评论
为什么被折叠?



