How to cancel a background worker with sleep?
-
09-02-2021 - |
Question
I'm having trouble canceling a background worker that has a Thread.Sleep(100)
in it.
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
int count;
try
{
count = int.Parse(textBox3.Text);
for (int i = 0; i < count; i++)
{
backgroundWorker1.ReportProgress((int)(((double)(i + 1) / count) * 1000));
//Computation code
Thread.Sleep(int.Parse(textBox4.Text));
}
}
catch (Exception ex)
{
request.DownloadData(url);
MessageBox.Show(ex.Message);
}
}
private void cancel_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
progressBar1.Value = 0;
}
If I remove the Thread.Sleep(100)
then the cancel works but otherwise it just keeps going (the progress bar doesn't stop).
EDIT: Added the rest of the code
Solution
When you call CancelAsync it just sets a property called CancellationPending
to true. Now your backgroundworker can, and should, periodically check if this flag is true, to gracefully finish its operation. So you need to split your background task into pieces where you can check for cancelation.
private void DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
while(true)
{
if(worker.CancellationPending)
{
e.Cancel = true;
return;
}
Thread.Sleep(100);
}
}
OTHER TIPS
Use Thread.Interrupt to exit from WaitSleepJoin state when you want to cancel the background thread.
http://msdn.microsoft.com/en-us/library/system.threading.thread.interrupt.aspx