Normally, when I want to cancel a backgroundWorker in C# I will do something like this:
while (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT);
}
In one application there are a number of backgroundWorkers. Is it valid to use a helper-function to cancel the backgroundWorkers, like so?
CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are)
{
while (bgw.IsBusy)
{
bgw.CancelAsync();
are.WaitOne(BGW_CANCEL_TIMEOUT);
}
}
My concern is that instead of passing the objects in question into the function, copies are made, thereby defeating the purpose of having the fun开发者_如何学Pythonction. The main purpose of having the function is to reduce code space and make the application code more readable/maintainable.
No, this isn't okay. It causes deadlock when the BGW has a RunWorkerCompleted event handler. That handler cannot run until the main thread goes idle and re-enters the message loop. The IsBusy property will stay True until that event handler completes.
You have a time-out on the WaitOne call so at least your program won't hang completely. But when WaitOne() returns, the BGW is not yet completed, the RWC event handler hasn't run yet. The only practical alternative is for the RWC event handler to do whatever needs done when the cancellation is complete.
Your code is wrong.
Calling CancelAsync
merely sets the CancellationPending
flag on the BackgroundWorker to true
. Your code in the DowWork
event is expected to periodically check this flag and stop if the flag is true
.
Calling CancelAsync
many times will not do any good, and there shouldn't be any reason to freeze the UI thread until it actually cancels.
精彩评论