【发布时间】:2011-01-16 03:43:44
【问题描述】:
在 MSDN 中,Thread.Abort() 方法的描述说:“调用此方法通常会终止线程。”
为什么不总是?
在哪些情况下它不会终止线程?
还有其他可能终止线程吗?
【问题讨论】:
标签: c# .net multithreading
在 MSDN 中,Thread.Abort() 方法的描述说:“调用此方法通常会终止线程。”
为什么不总是?
在哪些情况下它不会终止线程?
还有其他可能终止线程吗?
【问题讨论】:
标签: c# .net multithreading
FileStream.Read() 到当前未接收任何内容的命名管道(在等待传入数据时读取调用块)将不会响应 Thread.Abort()。它保留在 Read() 调用中。
【讨论】:
我似乎无法中止陷入循环的线程:
//immortal
Thread th1 = new Thread(() => { while (true) {}});
如果在循环期间休眠,我可以中止线程:
//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
【讨论】:
在哪些情况下它不会终止线程?
这个问题是重复的。
What's wrong with using Thread.Abort()
还有其他终止线程的可能性吗?
是的。你的问题是你不应该启动一个你不能礼貌地停止的线程,它会及时停止。如果您必须启动一个线程,该线程可能 (1) 难以停止,(2) 有错误,或者最糟糕的是 (3) 对用户怀有敌意,那么正确的做法是让一个新进程,在新进程中启动线程,然后终止进程,当您希望线程停止运行时。唯一能保证不合作线程安全终止的是操作系统取消其整个进程。
有关详细信息,请参阅我对这个问题的过长回答:
Using lock statement within a loop in C#
相关的部分是最后我讨论的关于在中止线程之前应该等待线程杀死自己多长时间的注意事项。
【讨论】:
因为您可以在处理程序中捕获 ThreadAbortException 并调用 Thread.ResetAbort。
【讨论】:
Thread.Abort() 在线程上注入 ThreadAbortException。线程可以通过调用Thread.ResetAbort() 来取消请求。此外,还有某些代码部分,例如 finally 块,将在处理异常之前执行。如果由于某种原因线程卡在这样的块中,则永远不会在线程上引发异常。
由于调用者在调用Abort() 时对线程的状态几乎没有控制权,因此一般不建议这样做。而是将消息传递给请求终止的线程。
【讨论】:
如果线程持有锁并被中止/终止怎么办?资源仍然卡住
当线程调用时它工作正常 中止自身,但不被其他线程中止。 中止,强行终止 受影响的线程,即使它没有 完成了任务并且没有提供 清理的机会 资源
参考MSDN
【讨论】:
ThreadAborts 不会发生在 finally 块内或 BeginCriticalRegion 和 EndCriticalRegion 之间
【讨论】:
OT:有关并发性的全面、与语言无关、有问题且非常有趣的观点,请参阅Verity Stob!
【讨论】:
我遇到过线程太忙而无法听到 Abort() 调用的情况,这通常会导致 ThreadAbortingException 被抛出到我的代码中。
【讨论】:
为什么不总是? 在哪些情况下它不会终止线程?
对于初学者,线程可能会捕获ThreadAbortException 并取消它自己的终止。或者它可以执行一个计算,当你试图中止它时,它会永远持续下去。正因为如此,运行时不能保证线程在你要求它之后总是会终止。
ThreadAbortException还有更多:
当调用 Abort 方法来销毁线程时,公共语言运行时会引发 ThreadAbortException。 ThreadAbortException 是一个可以被捕获的特殊异常,但它会在 catch 块结束时再次自动引发。当引发此异常时,运行时会在结束线程之前执行所有 finally 块。 由于线程可以在 finally 块中进行无限计算,或调用
Thread.ResetAbort()取消中止,因此无法保证线程永远结束。
您不需要手动Abort() 一个线程。如果您简单地让线程中的方法返回,CLR 将为您完成所有繁琐的工作;这将正常结束线程。
【讨论】: