2

我的应用程序使用后台工作人员在循环内做一些工作。我有它,以便在每次循环迭代时,它检查取消挂起是否为真,如果是,则中断循环。好的,我的应用程序在完成当前循环迭代后停止处理。问题是我认为后台工作人员仍在运行 - 如果我单击按钮再次开始处理,我会收到一条错误消息,说明后台工作人员正忙。

我打算处置工人,但它是在表单运行时创建的,所以如果我处置它,它就不会再开始工作了。我真正想做的是告诉后台工作人员它已完成,如果我单击“停止处理”按钮,那么当我单击开始按钮时它就可以再次开始处理了!

我打算试试这个:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while (!backgroundWorker1.CancellationPending) 
    {
        // Start processing in a background thread so the GUI remains responsive,
        // pass in the name of the text file produced by 
        // PFDR FilenameLogic(txtLetterType.Text); 
    } 
}
4

4 回答 4

6

创建工作人员时,设置worker.WorkerSupportsCancellationtrue. 现在处理程序内部,DoWork您必须定期(最常见的是,在某个循环的开始等)检查worker.CancellationPending- 如果为真,则设置e.Cancel = true;(以便您可以区分完成和取消)、清理和退出(return;)。现在您的取消按钮可以调用worker.CancelAsync();,它会适当地行动。

于 2013-04-17T10:00:42.663 回答
5

与 Marc Gravell 的答案相同,但您似乎没有遵循。

你设置 e.cancel = true 吗?

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 1; i <= 10; i++)
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    // Perform a time consuming operation and report progress.
                    System.Threading.Thread.Sleep(500);
                    worker.ReportProgress(i * 10);
                }
            }
        }
于 2013-04-17T10:10:15.443 回答
1

我几乎没有找到如何通过停止按钮取消Backgroundworker的好方法:

我的 App 看起来像这样,两个按钮和一个进度条:

在此处输入图像描述

按下停止按钮后,它看起来像这样:

在此处输入图像描述

对于 Start button click 方法,代码检查 BGW 是否忙。如果没有启动 BGW:

private void btnStart_Click(object sender, EventArgs e)
    {


        //BGW
        if (!backgroundWorker1.IsBusy)
        {

            backgroundWorker1.RunWorkerAsync();

        }



    }

停止按钮调用以下方法,该方法将标志CancellationPending设置为 true:

        private void btnStop_Click(object sender, EventArgs e)
    {
        backgroundWorker1.CancelAsync();
    }

这个标志可以在 backgroundWorker1 _DoWork方法中使用,该方法负责处理高耗时函数:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i <= 100; i++)
        {

            backgroundWorker1.ReportProgress(i);
            Thread.Sleep(100);



            if (backgroundWorker1.CancellationPending && backgroundWorker1.IsBusy)
            {
                e.Cancel = true;
                return;
            }
        }
    }

现在到了棘手的部分,因为在关闭额外线程之前,您必须检查backgroundWorker1 _ProgressChanged中的e对象是否被取消!!!!!!否则你会得到一个错误

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        int i = 0;

        if (!e.Cancelled)
        {
            i = (int)(e.Result);
        }
        else
        {
            i = 0;
        }

        // Check to see if an error occurred in the
        // background process.
        if (e.Error != null)
        {
            MessageBox.Show(e.Error.Message);
            return;
        }

        // Check to see if the background process was cancelled.
        if (e.Cancelled)
        {
            MessageBox.Show("Processing cancelled.");
            return;
        }

        // Everything completed normally.
        // process the response using e.Result
        MessageBox.Show("Processing is complete.");

    }

额外信息: 不要忘记设置这些 Backgroundworker 标志:

            //Set WorkerReportsProgress true - otherwise no ProgressChanged active
        backgroundWorker1.WorkerReportsProgress = true;
        backgroundWorker1.WorkerSupportsCancellation = true;

如果这个小教程有帮助--> 点赞

于 2017-03-02T13:47:33.360 回答
0

我似乎已经解决了这个错误 - 在 Backgroundworker DoWork 方法中我放了一段时间 CancelPending 不是真的,当它是真的时我设置 e.Cancel = true 现在似乎工作正常!

于 2013-04-17T13:51:57.423 回答