简体   繁体   中英

C#, Background worker

I have a sample WinForms application that uses the BackgroundWorker component. It works fine but when I hit the Cancel button to cancel the background thread it doesn't cancel the thread. When I hit the Cancel button to call .CancelAsync() method, then in RunWorkerCompleted event handler e.Cancelled Property always remains false . I think when I hit Cancel button it should be set to true.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
       // Wait 100 milliseconds.
       Thread.Sleep(100);
       // Report progress.
       if (backgroundWorker1.CancellationPending == true)
       {
           //label1.Text = "Cancelled by user.";
           break;
        }

        backgroundWorker1.ReportProgress(i);
     }
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // Change the value of the ProgressBar to the BackgroundWorker progress.
    progressBar1.Value = e.ProgressPercentage;
    // Set the text.
    label1.Text = e.ProgressPercentage.ToString();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled == true)
    {
        label1.Text = "Canceled!";
    }
    else if (e.Error != null)
    {
        label1.Text = "Error: " + e.Error.Message;
    }
    else
    {
         label1.Text = "Done!";
    }
}

private void button2_Click(object sender, EventArgs e)
{
    if (backgroundWorker1.WorkerSupportsCancellation == true)
    {
        // Cancel the asynchronous operation.
        backgroundWorker1.CancelAsync();
    }
}

The Cancelled property is still false because you break out of the loop and then allow the backgroundworker's DoWork function to end in the normal way. You never tell your backgroundworker component that the pending cancel was actually accepted.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 1; i <= 100; i++)
    {
        // Wait 100 milliseconds.
        Thread.Sleep(100);

        if (backgroundWorker1.CancellationPending)
        {
            e.Cancel = true;
            break;
        }

        // Report progress.
        backgroundWorker1.ReportProgress(i);
    }
}

The distinction is important, because sometimes you may want rollback work you've already done when you detect the CancellationPending request, and so it may be a while before you actually finish with the cancel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM