如何“完全”杀死后台工作者?

我正在编写一个Windows应用程序,它反复运行一系列数字IO操作。

当用户点击一个“START”button时,这个动作序列就开始了,后台工作者在backgroundWorker1_DoWork()中完成。

不过,有些情况下我得到“这个背景工作者正在忙着…….”的错误信息。

我正在考虑在代码中实现以下内容:在开始另一个操作序列之前,使用while循环“杀死”后台工作者:

if (backgroundWorker1.IsBusy == true) { backgroundWorker1.CancelAsync(); while (backgroundWorker1.IsBusy == true) { backgroundWorker1.CancelAsync(); } backgroundWorker1.Dispose(); } backgroundWorker1.RunWorkerAsync(); 

我想我主要担心的是,后台工作人员最终会被“杀害”吗? 如果有的话,完成它需要很长时间吗?

这个编码会让我陷入一个无限循环吗?

你可以使用像这样的东西(有关中止托pipe线程和有关ThreadAbortException的更多信息,请参阅Chris Sells的“ 使用Rotorpipe道传递ThreadAbortException 的深度 ”):

 public class AbortableBackgroundWorker : BackgroundWorker { private Thread workerThread; protected override void OnDoWork(DoWorkEventArgs e) { workerThread = Thread.CurrentThread; try { base.OnDoWork(e); } catch (ThreadAbortException) { e.Cancel = true; //We must set Cancel property to true! Thread.ResetAbort(); //Prevents ThreadAbortException propagation } } public void Abort() { if (workerThread != null) { workerThread.Abort(); workerThread = null; } } } 

用法:

 backgroundWorker1 = new AbortableBackgroundWorker(); //... backgroundWorker1.RunWorkerAsync(); if (backgroundWorker1.IsBusy == true) { backgroundWorker1.Abort(); backgroundWorker1.Dispose(); } 

我认为线程应该尽可能地对自己资源负责, 包括自己的一生。

杀掉超出范围的线程通常是一个坏主意。 被devise为将消息传递给线程以closures自己的应用程序往往会涉及multithreading行为的问题less得多。

一个线程应该监视所述消息,该消息可以像由另一个线程设置的布尔值一样简单,并由该监视线程及时读取,并且尽可能快closures。

这意味着如果它应该寻找消息:

  • 在主循环中,如果有的话。
  • 定期在任何长期运行的循环中。

closures消息的线程应该等待(但是不要停止GUI,当然)。

请注意,对于具有特定function的线程化环境还有其他可能性,例如线程可以将自己标记为可以随意取消的情况,以允许外部查杀变得更安全。

但是,通过构build您的应用程序来让一个线程掌握自己的命运通常还是比较容易的。

我把它放在一起,(我认为)做这项工作。 请让我知道如果我可以closures。 这是一个如何工作的简单例子。

 var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true}; backgroundWorker.DoWork += (sender, args) => { var thisWorker = sender as BackgroundWorker; var _child = new Thread(() => { //..Do Some Code }); _child .Start(); while (_child.IsAlive) { if (thisWorker.CancellationPending) { _child.Abort(); args.Cancel = true; } Thread.SpinWait(1); } }; backgroundWorker.RunWorkerAsync(parameter); //..Do Something... backgroundWorker.CancelAsync(); 

由于后台工作人员是线程池的一部分,我们不想中止它。 但是我们可以在内部运行一个线程,我们可以允许中止发生。 然后backgroundWorker基本上运行,直到子线程完成,或者我们发信号去终止进程。 后台工作线程然后可以返回到读取池。 通常,我将把它包装在一个助手类中,并通过委托方法传递后台线程作为参数传入并在子线程中运行。

请有人让我知道,如果我撞我的头靠在墙上,但它似乎工作正常..但多数民众赞成在线程的问题是不是..你可以得到不同的结果,当你在不同的时间运行。

 public class abortableBackgroundworker: BackgroundWorker { public bool Kill = false; protected override void OnDoWork(DoWorkEventArgs e) { var _child = new Thread(() => { while (!Kill) { } e.Cancel = true;//..Do Some Code }); _child.Start(); base.OnDoWork(e); } } 

你把kill设置为true来杀死线程并且不会中止问题:)

我有同样的问题,我不知道这是否会帮助,但我猜你的后台工作人员有一个循环内或将退出。 你需要做的是把你的循环内。

放在你的后台工作者:

 while (backgroundworker1.CancellationPending == false) { //Put your code in here } 

要杀死这个背景工作者,你可以放入你的button:

 BackgroundWorker1.CancelAsync() 

我希望这有帮助。