Tag Archives: backgroundworker

Using a BackgroundWorker (thread)

The BackgroundWorker class can be used to start a background worker thread. Worker threads are typically used to perform lengthy task which would otherwise block the GUI or to perform simultaneous processing. Nowadays most computers have dual or quad core CPU’s Single thread application will not benefit from the additional cores.

Backround worker is a wrapper class for thread management. It can be dragged on the form in the designer or created in code. It is important to remember one BackgroundWorker instance can only serve one thread simultaneously!

Some code

void init()
{
  //Create a new instance, can also be done in the designer
   bw = new BackgroundWorker();

   //This event will be the main body of the thread
   bw.DoWork +=new DoWorkEventHandler(bw_DoWork);

   //Called when the thread ends gracefuly
   bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
   //Set to true to allow the thread to be canceled
   bw.CancellationPending = true;
   //Must be set to allow the DoWork event to call the ReportProgress method.
   bw.WorkerReportsProgress = true;

   //Called when the DoWork event calls ReportProgress
   bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

   //Run the thread (DoWork event)
   bw.RunWorkerAsync();
}

The code above just setups the event handlers. There are other event handler for e.g. cancellation support.
The BackGroundWorker object is shared between the two threads.

The following function is called in the context of the thread which created the BackgroundWorker, typically the GUI thread.

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
   MessageBox.Show("Progress " +  e.ProgressPercentage);
}

You can use the e.UserState which by default is the argument optionally passed to the RunWorkerAsync method. If the bw.ReportProgress is called with an extra argument this will beĀ  the e.UserState object. It is strongly recommended to use a value type or to clone a reference object since it may be accessed simultaneously otherwise. The worker thread will NOT wait for this event to complete! (which is a good thing!)

The following event is called in the context of the creating thread also. It is called when the thread completes. But only when the threads exits itself not when it’s terminated forcefully.

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   MessageBox.Show("Complete");
}

This code runs in the worker thread, it is the actual threads body.

void bw_DoWork(object sender, DoWorkEventArgs e)
{
   BackgroundWorker bw = sender as BackgroundWorker;

   int t;
   for (t = 0; t < 100; t += 10)
   {
      if (e.CancellationPending)
      {
         e.Cancel = true;
         return;
      }

      bw.ReportProgress(t);
      System.Threading.Thread.Sleep(1000);
   }
}

The CancellationPending value is set by the CancelAsync method called from the creating thread.

Lastest update in June 2011, inital post in June 2011