假设我们有一些代码在单独的线程中运行:
private static void ThreadFunc() {
ulong counter = 0;
while (true) {
try {
Console.WriteLine( "{0}", counter++ );
}
catch (ThreadAbortException) {
Console.WriteLine( "Abort!" );
}
}
}当调用Thread.Abort()时,会不会在catch块之外抛出异常?
发布于 2009-12-07 03:20:33
实际上是的,ThreadAbortException是特别的。即使您处理了它,它也会在try/catch/finally结束时由CLR自动重新抛出。(正如注释中所指出的,可以使用ResetAbort来抑制它,但到那时代码就会变得臭名昭著。)
更不用说,即使在try/catch/finally之外没有明显的可执行代码,循环的每次迭代都会在一小段时间内超出作用域,因此中止可能发生在try块之外。
除非您真的在catch块中执行某些操作,否则我将只执行一次try/finally,不用担心ThreadAbortException。有更好的方法可以在不使用Thread.Abort的情况下中止线程,这不仅会在不可预知的时间点混乱地中断您的代码,而且也不能保证正常工作,因为如果您的线程当前正在调用某些非托管代码,则在控制返回到托管代码之前,该线程不会中止。
最好使用某种类型的同步原语,比如ManualResetEvent,作为告诉线程何时退出的标志。您甚至可以使用布尔值字段来实现此目的,这就是BackgroundWorker所做的。
发布于 2009-12-07 03:25:26
是。我怀疑你是在问,因为线程中断只发生在线程可能阻塞(或者它已经被阻塞)的时候--例如IO。
对于中止没有这样的保证。基本上,它可以在任何时候发生,尽管存在延迟中止区域,例如constrained execution regions和catch/finally块,在这些区域中,只记住中止请求,并且线程在退出该区域时中止。
同步线程中止(即中止你自己的线程)是相当安全的,但是异步中止(中止不同的线程)几乎总是一个坏主意。有关更多信息,请阅读"Concurrent Programming on Windows" by Joe Duffy。
编辑:正如Eric在下面提到的,中止另一个线程也不能保证会有任何实际效果。引用下面的评论:
我会说,如果线程退出该区域,它就会中止,并强调
Thread.Abort是完全不可靠的。如果一个线程因为被困在无限循环中而被中止,那么如果该循环在这样的区域中,它将不会中止。这也是为什么Thread.Abort不是一个好主意的另一个原因;如果你不能依赖于期望的效果实际发生,那么你为什么要调用这个方法呢?
发布于 2009-12-07 03:20:20
我不是100%满足你的要求,但我想指出的是,你永远不可能吞下一个ThreadAbortException
当调用Abort方法以销毁线程时,公共语言运行库将引发
ThreadAbortException。ThreadAbortException是一个可以捕获的特殊异常,但它将在块的末尾自动再次引发。
您是在问是否可以使用try/catch捕获在另一个线程中抛出的ThreadAbortException?如果这是你的问题,那么不,你不能。
https://stackoverflow.com/questions/1856286
复制相似问题