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 类的更多信息,请参见 如何:在后台运行操作

请参见

任务

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

其他资源

Multithreading in Visual Basic