杀死.NET线程

Jor*_*nco 19 c# multithreading abort

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

Joh*_*ica 48

别打电话Thread.Abort()!

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

while (keepGoing)
{
    /* Do work. */
}
Run Code Online (Sandbox Code Playgroud)

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

try
{
    while (keepGoing)
    {
        /* Do work. */
    }
}
catch (ThreadInterruptedException exception)
{
    /* Clean up. */
}
Run Code Online (Sandbox Code Playgroud)

  • 使用异常处理来控制程序流是一个可怕的想法.请改用WaitHandle. (6认同)
  • 马克,如果你的线程阻塞输入怎么办?你需要让它以某种方式停止?它可以无限期地阻塞,因此中断它并处理异常是唯一可以让它退出的方法. (6认同)
  • 我不认为这太可怕了.如果你的循环不够紧,并且在最终知道它应该退出之前可能需要30秒的处理,异常是阻止它的最佳方法. (5认同)

Jon*_*n B 26

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

volatile bool shutdown = false;

void RunThread()
{
   while (!shutdown)
   {
      ...
   }
}

void StopThread()
{
   shutdown = true;
}
Run Code Online (Sandbox Code Playgroud)

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


Mar*_*ann 9

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

在你的主题中,你可以:

private void RunThread()
{
    while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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


Bri*_*eon 7

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

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

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

  • +1.你能提供一个通过等待句柄杀死/停止线程的简单例子吗? (2认同)