BackgroundWorker Component Overview

There are many commonly performed operations that can take a long time to execute. For example:

Image downloads

Web service invocations

File downloads and uploads (including for peer-to-peer applications)

Complex local computations

Database transactions

Local disk access, given its slow speed relative to memory access

Operations like these can cause your user interface to hang while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker component provides a convenient solution.

The BackgroundWorker component gives you the ability to execute time-consuming operations asynchronously ("in the background"), on a thread different from your application's main UI thread. To use a BackgroundWorker, you simply tell it what time-consuming worker method to execute in the background, and then you call the RunWorkerAsync method. Your calling thread continues to run normally while the worker method runs asynchronously. When the method is finished, the BackgroundWorker alerts the calling thread by firing the RunWorkerCompleted event, which optionally contains the results of the operation.

The BackgroundWorker component is available from the Toolbox, in the Components tab. To add a BackgroundWorker to your form, drag the BackgroundWorker component onto your form. It appears in the component tray, and its properties appear in the Properties window.

To start your asynchronous operation, use the RunWorkerAsync method. RunWorkerAsync takes an optional object parameter, which can be used to pass arguments to your worker method. The BackgroundWorker class exposes the DoWork event, to which your worker thread is attached through a DoWork event handler.

The DoWork event handler takes a DoWorkEventArgs parameter, which has an Argument property. This property receives the parameter from RunWorkerAsync and can be passed to your worker method, which will be called in the DoWork event handler. The following example shows how to assign a result from a worker method called ComputeFibonacci. It is part of a larger example, which you can find at How to: Implement a Form That Uses a Background Operation.

// This event handler is where the actual,// potentially time-consuming work is done.privatevoid 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.
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

When using multithreading of any sort, you potentially expose yourself to very serious and complex bugs. Consult the Managed Threading Best Practices before implementing any solution that uses multithreading.