Sometimes a smart client application needs to do a lengthy operation that can slow down the performance of the whole application and make it unresponsive. This can be solved by executing the operation in a separate thread using the .NET Framework's BackgroundWorker control. The BackgroundWorker executes such operations asynchronously in a thread separate from the application's main UI thread. A thread can be defined as an operation that is executed simultaneously and independently of the rest of the application.

The following example demonstrates the use of the BackgroundWorker control. The code requires a ProgressBar, 2 Buttons and a BackgroundWorker, they should be named progressBar1, startButton, cancelButton and backgroundWorker1 respectively. And set backgroundWorker1's WorkerReportsProgress and WorkerSupportsCancelation properties to True.

    private void startButton_Click(object sender, EventArgs e)
    {
        //prevent the user from clicking the button before 
        //the process is complete
        startButton.Enabled = false;

        //run the background thread
        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i <= 100; i++)
        {
            if (backgroundWorker1.CancellationPending == true)
            {                    
                e.Cancel = true;  
            }
            else
            {
                //send backgroundWorker1_ProgressChanged the value of i
                backgroundWorker1.ReportProgress(i);

                //imagine this is a lengthy process
                System.Threading.Thread.Sleep(100);                   
            }
        }
    }

    private void backgroundWorker1_ProgressChanged(
        object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }

    private void backgroundWorker1_RunWorkerCompleted(
        object sender, RunWorkerCompletedEventArgs e)
    {
        //reset the controls after 
        startButton.Enabled = true;
        progressBar1.Value = 0;
    }

    private void cancelButton_Click(object sender, EventArgs e)
    {
        //set the CancellationPending property to true
        backgroundWorker1.CancelAsync();
    }

The operation that needs a separate thread is written in the DoWork event of backgroundWorker1. When backgroundWorker1.RunWorkerAsync() method is called, a thread is created and the contents of DoWork are executed in it asynchronously. The backgroundWorker1.ReportProgress() method call executes the ProgressChanged event that can be used to update a ProgressBar. The argument passed to backgroundWorker1.ReportPrgress() is a Percentage that is passed to ProgressChanged in e.ProgressPercentage.