停止背景工作者

时间:2013-04-17 09:55:45

标签: c# .net backgroundworker

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

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

我打算试试这个:

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 个答案:

答案 0 :(得分:6)

创建工作人员时,请将worker.WorkerSupportsCancellation设置为true。现在里面 DoWork处理程序,你必须定期(最常见的是,在某个循环开始时等)检查worker.CancellationPending - 如果是,则设置{{1 (这样你可以区分完成和取消),清理和退出(e.Cancel = true;)。现在,您的取消按钮可以调用return;,它将采取相应的行动。

答案 1 :(得分: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);
                }
            }
        }

答案 2 :(得分:1)

我几乎找不到如何取消 背景工作者而不是 停止按钮 的好方法:

我的应用程序看起来像这样,两个按钮和一个进度条:

enter image description here

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

enter image description here

对于“开始”按钮单击方法,代码会检查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;

如果这个小教程很有用 - &gt;大拇指

答案 3 :(得分:0)

我似乎已经解决了错误 - 在Backgroundworker DoWork方法中,我放了一段时间取消启用不正确,当它成立时我设置了e.Cancel = true它现在似乎工作正常!