首页 文章

停止背景工作者

提问于
浏览
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 回答

  • 0

    与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);
                    }
                }
            }
    
  • 6

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

  • 5

    我几乎没有找到一个很好的方法如何取消 Backgroundworker Stop Button

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

    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 对象是否被取消!!!!!否则你会得到 Error .

    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.");
    
        }
    

    Extra information: 别忘了设置这些Backgroundworker标志:

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

    如果这个小教程很有帮助 - >拇指向上

  • 1

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

相关问题