需要帮助来停止BackgroundWorker线程

时间:2011-02-14 11:52:12

标签: c# window

需要帮助来停止BackgroundWorker线程。 我试图阻止后台工作线程。这就是我在做的事情:

点击停止按钮(UI图层):

if (backgroundWorker.IsBusy == true && 
    backgroundWorker.WorkerSupportsCancellation == true)
{
    backgroundWorker.CancelAsync();
}

在DoWork事件(UI层)上:

if ((backgroundWorker.CancellationPending == true))
{
     e.Cancel = true;
}
else
{
    //Function which progresses the progress bar is called 
    //here with its definition in business layer 
}

一旦DoWork事件被触发并且我的程序控件在Business层中定义的函数中,我如何恢复到DoWork事件以设置'e.Cancel = true'?

5 个答案:

答案 0 :(得分:3)

设置e.Cancel什么都不做,如果CancellationPending为true,你需要使用return或其他任何东西(在你停止你正在做的事情之后)基本上打破DoWork()。

类似的东西:

private void DoWork(...)
{
    // An infinite loop of work!
    while (true) 
    {
        // If set to cancel, break the loop
        if (worker.CancellationPending) 
            break;

        // Sleep for a bit (do work)
        Thread.Sleep(100);
    }
}

DoWork()在一个单独的线程中执行到UI线程,您可以使用BackgroundWorkr.ReportProgress()向UI线程报告。

答案 1 :(得分:2)

DoWork将在其自己的线程中运行,并且不依赖于GUI线程。

你几乎所有事情都是正确的。从GUI线程中,将CancellationPending设置为true

DoWork方法中,您可能有某种循环。

您可以在此检查CancellationPending == true,但除了将e.Cancel设置为true之外,还要包含return调用以使方法返回并有效地停止工作。如果连接方法,这也会导致在GUI线程上触发WorkerCompleted事件。

如果DoWork方法执行一些未分成多个部分的长任务(例如,如果您的DoWork方法如下所示:

void DoWork( (object sender, DoWorkEventArgs e)
{
   myClass.SomeLongOperation();
}

然后你运气不好,因为你需要手动检查CancellationPending方法中的DoWork才能阻止它。如果DoWork本身“挂起”并等待您无法控制的操作,则无法通过设置CancellationPending来阻止它(以任何有序的方式) GUI线程。

答案 2 :(得分:2)

  

一旦DoWork事件被触发并且我的程序控件在Business层中定义的函数中,我如何恢复到DoWork事件以设置'e.Cancel = true'?

你没有。如果您希望在执行业务层期间取消,则您的业务层必须支持取消。所以,你有两个选择:

  1. 在您的DoWork方法中,只调用短时间业务层方法并检查其间的CancellationPending。
  2. 使您的业务层方法可以取消注意,即将BackgroundWorker传递给他们并让他们定期检查CancellationPending(并且一旦转为true就重新运行)。

答案 3 :(得分:0)

继续检查逻辑的else部分中的CancellationPending = True Flag,并在true时返回。

答案 4 :(得分:0)

代码e.Cancel = true仅在BackgroundWorker上设置一个状态,以便它知道它已被取消,它实际上不会取消该过程。

您必须检查方法循环内的CancellationPendingbreakreturn

void DoWork(object sender, DoWorkEventArgs e) {
    for (int i = 0; i < length; i++) {
        if(e.CancellationPending) {
            return;
        }
        // Long running code
    }
}