background worker class cancellation, sets cancellation pending flag but doesn't quit

5.2k views Asked by At

I call obackgroundworker.CancelAsync(); on a background worker currently doing some work in another thread and then using while (obackgroundworker.IsBusy == true) to wait for it to finish before quitting the application (in case the user changes their mind while the thread is away processing and I want to close down cleanly)

The flat for cancellation pending is set to true correctly but the thread doesn't quit, in the worker thread i have:

backgroundworker obackgroundworker = (backgroundworker)sender;
if (obackgroundworker.cancellationpending == true)
     e.cancel = true;              

which should check to see if a cancellation is pending and then set the cancelled flag to true, and i think that also causes the thread to actually terminate...? or is there some other function I need to call from the thread when it detects a cancellation to actually end?

I've read a lot of examples that use background workers exactly like above and don't report any problems.

Sources:

http://www.albahari.com/threading/part3.aspx http://www.dotneat.net/2009/02/10/BackgroundworkerExample.aspx http://www.codeproject.com/KB/cpp/BackgroundWorker_Threads.aspx

Thanks

2

There are 2 answers

0
Thomas Levesque On BEST ANSWER

Setting e.Cancel to true doesn't stop the execution of the BackgroundWorker, it only indicates that the operation was canceled so that you can check it in the RunWorkerCompleted event. You need to stop the task by returning from the DoWork event handler :

BackgroundWorker obackgroundworker = (BackgroundWorker)sender;
if (obackgroundworker.CancellationPending == true)
{
     e.Cancel = true;
     return;
}
0
Jon Skeet On

No, just setting the property won't cause the thread to terminate. You should return from your method at that point. For example, here's code from the first of your links:

if (bw.CancellationPending) {
    e.Cancel = true;
    return;
}

Note the return statement, so that the method finishes.

Of course, if you're doing this from some method deep in the stack, you'll need to make sure that the caller knows to terminate as well, etc - but normally for background worker threads, it's the "top level" method that checks the CancellationPending property anyway, so usually just returning is fine.