首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ThreadAbortException

ThreadAbortException
EN

Stack Overflow用户
提问于 2009-12-07 03:16:30
回答 3查看 59.3K关注 0票数 47

假设我们有一些代码在单独的线程中运行:

代码语言:javascript
复制
private static void ThreadFunc() {
    ulong counter = 0;

    while (true) {

        try {
            Console.WriteLine( "{0}", counter++ );
        }
        catch (ThreadAbortException) {
            Console.WriteLine( "Abort!" );
        }

    }
}

当调用Thread.Abort()时,会不会在catch块之外抛出异常?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-12-07 03:20:33

实际上是的,ThreadAbortException是特别的。即使您处理了它,它也会在try/catch/finally结束时由CLR自动重新抛出。(正如注释中所指出的,可以使用ResetAbort来抑制它,但到那时代码就会变得臭名昭著。)

更不用说,即使在try/catch/finally之外没有明显的可执行代码,循环的每次迭代都会在一小段时间内超出作用域,因此中止可能发生在try块之外。

除非您真的在catch块中执行某些操作,否则我将只执行一次try/finally,不用担心ThreadAbortException。有更好的方法可以在不使用Thread.Abort的情况下中止线程,这不仅会在不可预知的时间点混乱地中断您的代码,而且也不能保证正常工作,因为如果您的线程当前正在调用某些非托管代码,则在控制返回到托管代码之前,该线程不会中止。

最好使用某种类型的同步原语,比如ManualResetEvent,作为告诉线程何时退出的标志。您甚至可以使用布尔值字段来实现此目的,这就是BackgroundWorker所做的。

票数 74
EN

Stack Overflow用户

发布于 2009-12-07 03:25:26

是。我怀疑你是在问,因为线程中断只发生在线程可能阻塞(或者它已经被阻塞)的时候--例如IO。

对于中止没有这样的保证。基本上,它可以在任何时候发生,尽管存在延迟中止区域,例如constrained execution regions和catch/finally块,在这些区域中,只记住中止请求,并且线程在退出该区域时中止。

同步线程中止(即中止你自己的线程)是相当安全的,但是异步中止(中止不同的线程)几乎总是一个坏主意。有关更多信息,请阅读"Concurrent Programming on Windows" by Joe Duffy

编辑:正如Eric在下面提到的,中止另一个线程也不能保证会有任何实际效果。引用下面的评论:

我会说,如果线程退出该区域,它就会中止,并强调Thread.Abort是完全不可靠的。如果一个线程因为被困在无限循环中而被中止,那么如果该循环在这样的区域中,它将不会中止。这也是为什么Thread.Abort不是一个好主意的另一个原因;如果你不能依赖于期望的效果实际发生,那么你为什么要调用这个方法呢?

票数 21
EN

Stack Overflow用户

发布于 2009-12-07 03:20:20

我不是100%满足你的要求,但我想指出的是,你永远不可能吞下一个ThreadAbortException

当调用Abort方法以销毁线程时,公共语言运行库将引发ThreadAbortExceptionThreadAbortException 是一个可以捕获的特殊异常,但它将在块的末尾自动再次引发。

您是在问是否可以使用try/catch捕获在另一个线程中抛出的ThreadAbortException?如果这是你的问题,那么不,你不能。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1856286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档