Cancel BackgroundWorker, how to prevent a race when it is already completed

I use BackgroundWorker to do long calculations (only one such calculation at a time).

The user has the option to cancel the worker (calling employee.CancelAsync).

In the worker.DoWork method, I periodically check the cancel cancel flag and then return from the method.

Then the Completed event rises from the worker, and I can verify that the worker has been canceled. In addition, and this is important, I do an additional cleanup when a cancellation is detected.

I am sure that a problem may arise if the user cancels the work and has already returned from the DoWork method. In this case, I would really like to know that the worker was canceled so that I can clean ...

Is there a better way to handle a cancellation procedure with a worker clearing?

+5
source share
5 answers

Your event handler DoWorkperiodically checks BackgroundWorker.CancellationPendingand sets DoWorkEventArgs.Cancelto true before returning if it was canceled.

The event handler RunWorkerCompletedmust check the property RunWorkerCompletedEventArgs.Cancelledto determine if the event handler is canceled DoWork(set DoWorkEventArgs.Cancelto true).

, (BackgroundWorker.CancellationPending - true), (RunWorkerCompletedEventArgs.Cancelled - false). , , , , ( ), - , ).

, - , .

- , CancellationPending, , BackgroundWorker, . , , BackgroundWorkers. , .

, DoWorkEventArgs.Cancel, , (, ), , .

+2

, . , CancellationPending, , false DoWork , DoWork . , . , , :

Public Class CancelTrackingBackgroundWorker
  Inherits System.ComponentModel.BackgroundWorker
  Public CancelRequested As Boolean = False
  Public Sub TrackableCancelAsync()
    Me.CancelRequested = True
    Me.CancelAsync()
  End Sub
End Class

( CancelAsync, , .) TrackableCancelAsync CancelAsync, CancelRequested . ( ), .

+2

RunWorkerCompleted, . :

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
  var bgw = sender as BackgroundWorker;
  if (e.Cancelled || bgw.CancellationPending) {
    // etc..
  }
}
+1

, , ?

​​

private void MyThreadMethod()
{
    try
    {
        // Thread code
    }
    finally 
    {
        // Cleanup
    }
}

, , .

0

, , , , "", , DoWork.

, .

Also - if the method is DoWorkfinished, then the user does not need to "Cancel" anything - or I'm missing something. In this case, even if you do not turn off the cancel button, you do not need to do anything else.

Why do you need to see the cancellation flag after the employee has completed his work? Do you still want to undo what has ever been changed?

0
source

All Articles