Just a quick note about an issue that seems deceptively simple to introduce… If you are using the BackgroundWorker in your app and you've set it up to support cancellation, be careful how you write your code that watches for cancellation.

BackgroundWorker has an event DoWork, which passes DoWorkEventArgs. This derives from CancelEventArgs, which has a property named Cancel. The unsuspecting developer (like me) might assume that e.Cancel is the property to check for detecting if the work has been cancelled. You might write something like:

while(!e.Cancel)
{
  …
}

This seems reasonable, but it's gonna fail, and not in a kind way either. Instead, your loop will continue forever. Yech!

The appropriate way is to check the CancellationPending property of the BackgroundWorker instance. The cleanest way to get this is to cast the sender parameter of your DoWork event handler to a BackgroundWorker. Then you can check the CancellationPending property from this reference.

So the following would be more proper…

private void DoWork(object sender, DoWorkEventArgs e)
{
  var worker = sender as BackgroundWorker;
 
  while (!worker.CancellationPending)
  {
    …
  }
 
  if (worker.CancellationPending)
  {
    e.Cancel = true;
  }
}

So… Why does DoWorkEventArgs inherit from CancelEventArgs anyway? Just to trip us up? Well, not exactly. It is there so that the DoWork event handler can indicate whether it completed normally, or stopped prematurely due to a cancellation request. If you detect CancellationPending, then you can set e.Cancel = true. Then the RunWorkCompleted event will fire with a flag indicating that the work was indeed cancelled, as requested.

If I had my way, I think this API could have been coded with a little more explicit naming to avoid this mistake. And, I'd argue that using CancelEventArgs is a bit of a non-standard use of the class. Typically, CancelEventArgs is used to allow an event handler to request further processing by the sender. Using it as a means to report that the DoWork event handler cancelled is, IMHO, a little non-standard. I think simply adding a property to the DoWorkEventArgs named "DoWorkCancelled" might be better. Either way, it's not a big deal. Just an indication that I should read MSDN more carefully.

Hope that helps someone out there.

Cheers!