BackgroundWorker 组件概述

更新:2007 年 11 月

许多经常执行的操作可能需要很长的执行时间。例如:

  • 图像下载

  • 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 );
}
// 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 = (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.set_Result(new Long(ComputeFibonacci(System.Convert.ToInt32
        (e.get_Argument()), worker, e)));
    //e.Result = ComputeFibonacci((int)e.Argument, worker, e); 
} //backgroundWorker1_DoWork

有关使用事件处理程序的更多信息,请参见 事件和委托

警告:

使用任何一种多线程都可能引起极为严重和复杂的 bug。在实现任何一种使用多线程处理的解决方案之前,请先参考 托管线程处理的最佳做法

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

请参见

任务

如何:实现使用后台操作的窗体

其他资源

多线程处理 (Visual Basic)