1

Is there a way to neatly cancel a long-running background worker, say, after a timeout?

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    ComplexRowContainer crc = (ComplexRowContainer)e.Argument;
    string filename = crc.AppFullPath;
    string calculatedChecksum = BuildChecksum(filename);

    e.Result = calculatedChecksum;
}

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    string newChecksum = (string)e.Result;
    if (newChecksum.Equals(oldChecksum))
    {
        MessageBox.Show("Same");
    }
    else
    {
        MessageBox.Show("Different");
    }
}

And I do need to modify it for cancel events. However, is there anything 'built-in' that can automatically cancel a long-running task or should I build a timer to cancel on timeout? Thanks.

timss
  • 9,982
  • 4
  • 34
  • 56
aqua
  • 3,269
  • 28
  • 41
  • As Xaqron suggested, you use a cancellation token and you have to poll this property occasionally inside your worker routine to see if you should stop doing whatever you are doing. The only other way to "abort" the task is with Thread.Abort() which is terrible and evil and should be avoided at all costs. – Mike Marynowski May 02 '13 at 02:16

2 Answers2

1

Actually, this is how to do it with BackgroundWorker:

  1. keep a reference to the BackgroundWorker when you start the thread
  2. Set WorkerSupportsCancellation to true before you call RunWorkerAsync
  3. While the BackgroundWorker is running, call CancelAsync on the reference you kept in order to signal cancellation.
  4. In the background routine, check CancellationPending periodically on the BackgroundWorker instance you get as the sender argument of the DoWork event. If CancellationPending is true, just return from the eventhandler.

If you want to do this with a timeout, you'd call CancelAsync from a timer event.

hbarck
  • 2,934
  • 13
  • 16
0

Is there a way to neatly cancel a long-running background worker, say, after a timeout?

To cancel a background worker you can use DoWorkEventArgs in DoWork event method by set e.Cancel = true. To cancel a long-running background worker you need to define which one method are take long and following comment from Mike Marynowski you should use Task to run it and use CancellationToken to cancel a long-running Task.

Some of info regarding to cancel a background worker you can take reference:

http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

is there anything 'built-in' that can automatically cancel a long-running task

Yes, you can take reference the link below.

Asynchronously wait for Task<T> to complete with timeout

or

How to cancel a task that is waiting with a timeout without exceptions being thrown

Community
  • 1
  • 1
Toan Vo
  • 1,270
  • 9
  • 19