C#BackgroundWorker.CancelAsync()与DoWorkEventArgs.Cancel

问题描述 投票:0回答:2

我想在我的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();),e.Cancel = false是否会使CancellationPending()的评估为假?

c# backgroundworker cancellation
2个回答
0
投票

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

DoWorkEventArgs.Cancel可以告诉RunWorkerCompleted Event该进程已取消。您不应使用在Exception中中止或结束的操作的结果。将DoWorkEventArgs.Cancel设置为true将将RunWorkerCompletedEventArgs.Canceled设置为true。 Wich也会将RunWorkerCompletedEventArgs.Result强制为throw an exception if accessed

我从BGW学习Multithrading时获得了一些非常古老的示例代码。它应该可以帮助您。

#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类是很好的多任务“训练轮子”。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.