2011-02-14 109 views
8

需要帮助来停止BackgroundWorker线程。 我想停止后台工作线程。这是我在做什么:需要帮助来停止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的事件被触发,我程序控制是在业务层定义的函数中,我如何恢复到DoWork事件来设置'e.Cancel = true'?

回答

2

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

你几乎一切正确。在GUI线程中,将CancellationPending设置为true

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

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

如果DoWork方法进行一些长期的任务,不分成部分(例如,如果您DoWork方法是这样的:

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

那么你的运气了,因为你需要手动检查CancellationPendingDoWork方法里面能够阻止它。如果DoWork本身从GUI设置CancellationPending“挂起”和你无法控制一个操作等待,你不能阻止它(在任何有序的方式)线程。

+1

。如果您>在DoWork中没有循环,那么它不会工作。 – stuartd

+1

@Stuart - 正如答案中所述,这是正确的。如果没有循环,没有强制关闭GUI线程中的线程的好方法。 –

+0

@ØyvindKnobloch-Bråthen - 请告诉我什么是从GUI线程强制杀死Backgroundworker线程的坏方法。 (DoWork中没有循环) – Zeeshanef

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线程()。

0

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

2

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

你不知道。如果您希望在执行业务层期间取消,那么您的业务层必须支持取消。因此,您有两种选择:

  1. 在您的DoWork方法中,只调用短时业务层方法并检查两者之间的CancellationPending。
  2. 使您的业务图层方法取消感知,即将BackgroundWorker传递给它们,并让它们定期检查CancellationPending(并且在它变为true时重新调用)。
0

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

您必须在您的方法循环中检查CancellationPending,并检查break it或return

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