C#Thread Termination和Thread.Abort()

use*_*375 82 .net c# multithreading

在MSDN中,Thread.Abort()方法的描述说:"调用此方法通常会终止线程."

为什么不总是?

在哪些情况下它不会终止线程?

有没有其他可能终止线程?

Bri*_*sen 57

Thread.Abort()ThreadAbortException在线程上注入一个.线程可以通过调用取消请求Thread.ResetAbort().此外,还有某些代码部分,例如finally在处理异常之前将执行的块.如果由于某种原因线程卡在这样的块中,则线程上永远不会引发异常.

由于调用者在调用时几乎无法控制线程的状态Abort(),因此通常不建议这样做.将消息传递给请求终止的线程.

  • 这取决于您如何在线程之间传递数据.例如,如果您的线程是具有任务队列的工作线程,则可以对PleaseTerminate消息进行排队,并让线程正常处理它. (4认同)

Eri*_*ert 52

在哪些情况下它不会终止线程?

这个问题是重复的.

使用Thread.Abort()有什么问题

是否有任何其他可能性来终止线程?

是.你的问题是,你永远不应该启动一个你不能礼貌地停止的线程,它会及时停止.如果你处于这样一种情况,你必须启动一个可能(1)难以停止的线程,(2)越野车,或者最糟糕的(3)对用户不利,那么正确的做法是做一个新进程,在新进程中启动线程,然后在希望线程关闭时终止进程.唯一可以保证不合作线程安全终止的是操作系统取消整个过程.

有关详细信息,请参阅我对此问题的过长答案:

在C#中的循环中使用lock语句

相关位是最后的位,我讨论了关于在中止之前等待线程自杀多长时间的考虑因素.

  • @Corvin:描述一个线程如何与另一个线程通信的两个线程之间的契约取决于在这些线程上运行的代码的作者.如果你有要求(1)线程X必须永远等待一个对象,并且(2)线程Y必须能够在有限的时间内干净地关闭线程X,那么我认为你有相互矛盾的要求; 决定哪一个获胜.如果是前者,那么线程Y将不得不等待.如果是后者,那么线程X不应该永远等待,它应该等待一小段时间. (5认同)
  • @Corvin,如果你把那个等待线程作为后台线程,那么在应用程序退出之前你不必关闭它. (2认同)

Joh*_*lla 17

为什么不总是?在哪些情况下它不会终止线程?

对于初学者,线程可以捕获ThreadAbortException并取消其自己的终止.或者它可以在您尝试中止时执行永远需要的计算.因此,运行时无法保证线程在您请求后始终终止.

ThreadAbortException 有更多:

当调用Abort方法来销毁线程时,公共语言运行库会抛出ThreadAbortException.ThreadAbortException是一个可以捕获的特殊异常,但它会在catch块的末尾自动再次引发.引发此异常时,运行时会在结束线程之前执行所有finally块.由于线程可以在finally块中执行无限制计算,或者调用Thread.ResetAbort()取消中止,因此无法保证线程将永远结束.

您不需要Abort()手动线程.如果您只是让线程中的方法返回,CLR将为您完成所有脏工作; 这将正常结束线程.


小智 6

FileStream.Read()到当前没有收到任何内容的命名管道(等待传入数据时读取调用块)将不响应Thread.Abort().它仍然在Read()通话中.


Col*_*lin 6

我似乎无法中止陷入循环的线程:

//immortal
Thread th1 = new Thread(() => { while (true) {}});
Run Code Online (Sandbox Code Playgroud)

但是,如果在循环期间休眠,我可以中止线程:

//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
Run Code Online (Sandbox Code Playgroud)


Asa*_*sad 5

如果一个线程持有一个锁并被中止/杀死怎么办?资源仍然停滞不前

当一个线程调用中止而不是其他线程时,它工作正常.中止,强制终止受影响的线程,即使它尚未完成任务并且没有提供清理资源的机会

参考MSDN


请参阅: 托管线程最佳实践