Jack
Jack

Reputation: 5768

How to cancel a background worker with sleep?

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

Upvotes: 1

Views: 2209

Answers (2)

dowhilefor
dowhilefor

Reputation: 11051

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);
        }
    }

Upvotes: 6

mircea
mircea

Reputation: 503

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

Upvotes: 0

Related Questions