BackgroundWorker 组件概述
许多经常执行的操作可能需要很长的执行时间。 例如:
图像下载
Web 服务调用
文件下载和上载(包括点对点应用程序)
复杂的本地计算
数据库事务
本地磁盘访问(相对于内存访问来说其速度很慢)
类似这样的操作可能导致用户界面在操作运行时挂起。 如果您需要用户界面的响应却遇到与此类操作关联的长时间延迟,BackgroundWorker 组件可以提供一种方便的解决方案。
使用 BackgroundWorker 组件,您可以在不同于应用程序的主用户界面线程的另一线程上异步(“在后台”)执行耗时的操作。 若要使用 BackgroundWorker,只需要告诉该组件要在后台执行的耗时的辅助方法,然后调用 RunWorkerAsync 方法。 在辅助方法以异步方式运行的同时,您的调用线程继续正常运行。 该方法运行完毕,BackgroundWorker 激发 RunWorkerCompleted 事件(可选择包含操作结果)向调用线程发出警报。
**“组件”选项卡的“工具箱”中提供了 BackgroundWorker 组件。 若要向窗体添加 BackgroundWorker,请将 BackgroundWorker 组件拖到窗体上。 该组件出现在组件栏中,该组件的属性出现在“属性”**窗口中。
若要启动异步操作,请使用 RunWorkerAsync 方法。 RunWorkerAsync 采用一个可选 object 参数,可以使用该参数将变量传递给辅助方法。 BackgroundWorker 类公开 DoWork 事件,您的辅助线程通过 DoWork 事件处理程序附加到该事件。
DoWork 事件处理程序采用一个 DoWorkEventArgs 参数,该参数具有 Argument 属性。 此属性接收来自 RunWorkerAsync 的参数,并可以传递至 DoWork 事件处理程序中调用的辅助方法。 下面的示例演示如何分配名为 ComputeFibonacci 的辅助方法的结果。 该示例摘自 如何:实现使用后台操作的窗体 中一个较大的示例。
' This event handler is where the actual work is done.
Private Sub backgroundWorker1_DoWork( _
ByVal sender As Object, _
ByVal e As DoWorkEventArgs) _
Handles backgroundWorker1.DoWork
' Get the BackgroundWorker object that raised this event.
Dim worker As BackgroundWorker = _
CType(sender, BackgroundWorker)
' Assign the result of the computation
' to the Result property of the DoWorkEventArgs
' object. This is will be available to the
' RunWorkerCompleted eventhandler.
e.Result = ComputeFibonacci(e.Argument, worker, e)
End Sub 'backgroundWorker1_DoWork
// This event handler is where the actual,
// potentially time-consuming work is done.
private void backgroundWorker1_DoWork(object sender,
DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
e.Result = ComputeFibonacci((int)e.Argument, worker, e);
}
// This event handler is where the actual,
// potentially time-consuming work is done.
void backgroundWorker1_DoWork( Object^ sender, DoWorkEventArgs^ e )
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
e->Result = ComputeFibonacci( safe_cast<Int32>(e->Argument), worker, e );
}
有关使用事件处理程序的更多信息,请参见 事件和委托。
警告
使用任何一种多线程都可能引起极为严重和复杂的 bug。 在实现任何一种使用多线程处理的解决方案之前,请先参考 托管线程处理的最佳做法。
有关使用 BackgroundWorker 类的更多信息,请参见 如何:在后台运行操作。