杀死.NET线程

我创建了一个运行某种方法的线程。 但有时我想杀死线程,即使它仍在工作。 我怎样才能做到这一点? 我尝试了Thread.Abort(),但它显示了一个消息框,说“线程已中止”。 我该怎么办?

不要调用Thread.Abort()

Thread.Abort很危险。 相反,你应该与线程合作,以便它可以安静地关闭。 需要设计线程,以便可以告诉它自杀,例如,当你想让线程停止时,你设置一个boolean keepGoing标志,你设置为false。 然后线程会有类似的东西

 while (keepGoing) { /* Do work. */ } 

如果线程可能在SleepWait阻塞,那么可以通过调用Thread.Interrupt()将其从这些函数中分离出来。 然后应该准备线程来处理ThreadInterruptedException

 try { while (keepGoing) { /* Do work. */ } } catch (ThreadInterruptedException exception) { /* Clean up. */ } 

你应该只打电话给Abort()作为最后的手段。 您可以使用变量来同步此线程:

 volatile bool shutdown = false; void RunThread() { while (!shutdown) { ... } } void StopThread() { shutdown = true; } 

这允许您的线程干净地完成它正在做的事情,让您的应用程序处于已知的良好状态。

最正确和线程安全的方法是使用WaitHandle在它应该停止时向线程发出信号。 我主要使用ManualResetEvent。

在你的主题中,你可以:

 private void RunThread() { while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100))) { // ... } } 

其中this.flag是ManualResetEvent的一个实例。 这意味着您可以从线程外部调用this.flag.Set()来停止循环。

WaitOne方法仅在设置标志时返回true。 否则,它将在指定的超时(示例中为100 ms)后超时,并且线程将再次运行循环。

杀死一个post并不是一个好主意。 最好发出信号表示它应该停止并让它优雅地结束。 有各种不同的方法可以做到这一点。

  • 如果被阻止,请使用Thread.Interrupt戳它。
  • 轮询一个标志变量。
  • 使用WaitHandle类发送信号。

我没有必要重新讨论如何使用每种方法,因为我已经在这个答案中这样做了。

中止线程是一个非常糟糕的主意,因为您无法确定线程在中止时正在执行的操作。

相反,有一个线程可以检查的属性,以及您的外部代码可以设置。 让线程在安全的地方退出时检查这个布尔属性。

我同意Jon B

 volatile bool shutdown = false; void RunThread() { try { while (!shutdown) { /* Do work. */ } } catch (ThreadAbortException exception) { /* Clean up. */ } } void StopThread() { shutdown = true; } 

还有我的WebServer类中杀死线程的例子……

https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948

我想说Abort是可以的,只要了解后果是什么……只要你在长时间运行的任务之前指示状态Abort会工作但是需要标志,例如(ShouldStop或ActionBranch等)

看看它的例子!