C# BackgroundWorker.CancelAsync() 与 DoWorkEventArgs.Cancel

C# BackgroundWorker.CancelAsync() vs DoWorkEventArgs.Cancel

我想在我的 BackgroundWorker 完成处理程序中使用 RunWorkerCompletedEventArgs.Cancelled 值,但文档不清楚 BackgroundWorker.CancelAsync()DoWorkEventArgs.Cancel(在后台工作程序中如何处理) ) 都会影响它。它们在功能上是否相同?

例如,这是...

private void _Worker_DoWork(object sender, DoWorkEventArgs e)
{
    (sender as BackgroundWorker).CancelAsync();
}

...相当于这个?

private void _Worker_DoWork(object sender, DoWorkEventArgs e)
{
    e.Cancel = true;
}

后者是否会导致 CancellationPending() 的后续评估为真?此外,如果后台工作者在外部被取消(即 myBW.CancelAsync(); 在 do work 处理程序之外),e.Cancel = false 会导致 CancellationPending() 的评估为假吗?

BackgroundWorker.CancelAsync() 会将 BackgroundWorker.CancellationPending 的值设置为 true,因此 DoEvent 代码可以检查它。

DoWorkEventArgs.Cancel 是用来告诉 RunWorkerCompleted 事件进程被取消了。您不应该使用已中止或以异常结束的操作的结果。将 DoWorkEventArgs.Cancel 设置为真会将 RunWorkerCompletedEventArgs.Canceled 设置为真。至极也将迫使 RunWorkerCompletedEventArgs.Resultthrow an exception if accessed.

我有一些非常古老的示例代码,是我在使用 BGW 学习多线程时留下的。应该对你有帮助。

#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
    if (!bgwPrim.IsBusy)
    {
        //Prepare ProgressBar and Textbox
        int temp = (int)nudPrim.Value;
        pgbPrim.Maximum = temp;
        tbPrim.Text = "";

        //Start processing
        bgwPrim.RunWorkerAsync(temp);
    }
}

private void btnPrimCancel_Click(object sender, EventArgs e)
{
    if (bgwPrim.IsBusy)
    {
        bgwPrim.CancelAsync();
    }
}

private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
    int highestToCheck = (int)e.Argument;
    //Get a reference to the BackgroundWorker running this code
    //for Progress Updates and Cancelation checking
    BackgroundWorker thisWorker = (BackgroundWorker)sender;

    //Create the list that stores the results and is returned by DoWork
    List<int> Primes = new List<int>();


    //Check all uneven numbers between 1 and whatever the user choose as upper limit
    for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
    {
        //Report progress
        thisWorker.ReportProgress(PrimeCandidate);
        bool isNoPrime = false;

        //Check if the Cancelation was requested during the last loop
        if (thisWorker.CancellationPending)
        {
            //Tell the Backgroundworker you are canceling and exit the for-loop
            e.Cancel = true;
            break;
        }

        //Determin if this is a Prime Number
        for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
        {
            if (PrimeCandidate % j == 0)
                isNoPrime = true;
        }

        if (!isNoPrime)
            Primes.Add(PrimeCandidate);
    }

    //Tell the progress bar you are finished
    thisWorker.ReportProgress(highestToCheck);

    //Save Return Value
    e.Result = Primes.ToArray();
}

private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    pgbPrim.Value = e.ProgressPercentage;
}

private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    pgbPrim.Value = pgbPrim.Maximum;
    this.Refresh();

    if (!e.Cancelled && e.Error == null)
    {
        //Show the Result
        int[] Primes = (int[])e.Result;

        StringBuilder sbOutput = new StringBuilder();

        foreach (int Prim in Primes)
        {
            sbOutput.Append(Prim.ToString() + Environment.NewLine);
        }

        tbPrim.Text = sbOutput.ToString();
    }
    else 
    {
        tbPrim.Text = "Operation canceled by user or Exception";
    }
}
#endregion

我个人认为 GUI 中的 BackgroundWorker class 是很好的多任务处理工具 "Training Wheels"。

不,它们不一样。 "CancelAsync()" 方法在 "backgroundworker" 的代码之外运行。 "CancellationPending" 可以在 "DoWork" 主体中检查,并且 "e.Cancel" 在 "DoWork" 中设置以在 "Completed" 方法中使用。
请参阅以下页面了解更多信息:
(https://www.c-sharpcorner.com/uploadfile/mahesh/backgroundworker-in-C-Sharp/)