【问题标题】:Why CLR re-throws ThreadAbortException?为什么 CLR 重新抛出 ThreadAbortException?
【发布时间】:2012-01-04 11:52:07
【问题描述】:

我从“Windows 上的并发编程”一书中得到以下代码:

void Main()
{
    try
    {
        try
        {
            Console.WriteLine("Inside Main Method");
            Thread.CurrentThread.Abort();
        }
        catch(ThreadAbortException)
        {
            Console.WriteLine("Inside First Catch");
            // Trying to swallow but CLR throws it again....
        }
    }
    catch(ThreadAbortException)
    {
        Console.WriteLine("Inside Second Catch");
        //Thread.ResetAbort();
    }
}

我很想知道为什么 CLR 会重新抛出 ThreadAbortException ?它一直这样做,直到我调用“Thread.ResetAbort()”。其次,是否有任何其他系统定义的异常得到 CLR 的特殊处理?

【问题讨论】:

  • 另请注意,调用 Thread.ResetAbort() 的代码需要特殊权限才能执行此操作。因此,如果您正在托管 CLR 或创建 AppDomain,您可能会使用此功能使中止线程更具确定性。

标签: c# multithreading clr threadabortexception


【解决方案1】:

这是一个特殊的例外,http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx,见备注。据我了解,发生这种情况的原因是 .Net 使您能够在线程关闭之前进行任何清理工作。

有关管道的信息请参阅此内容:http://ondotnet.com/pub/a/dotnet/2003/02/18/threadabort.html

【讨论】:

    【解决方案2】:

    我很想知道为什么 CLR 会重新抛出 ThreadAbortException?

    因为线程正在被中止。人们一直在处理所有异常,即使这样做很危险。如果一个错误记录例程让一个应该永远被销毁的线程保持活动状态,那将是很奇怪的,不是吗?

    是否有任何其他系统定义的异常得到 CLR 的特殊处理?

    是的,有几个。例如,栈外和内存外异常也有特殊的行为。

    【讨论】:

    • 感谢您的回答。只是想问一下,现在鉴于我知道这种行为,是否推荐将基于线程的代码封装在“ThreadAbortException”try-catch 块中?由于无论如何都会重新抛出异常,因此该行为可能会让不知道此异常行为方式的人感到惊讶。
    • @PawanMishra:我想到了两条好规则。第一个是“永不中止线程”。正常终止线程;如果不能,请终止整个过程。中止线程是非常危险的。其次,“永远不要处理你无能为力的异常。”当线程被中止时,从来没有什么好事可做。由于您永远不会中止线程,并且如果您这样做也永远不会处理异常,因此编写 catch 块有点毫无意义,对吧?
    • 重新询问 OP 的第二个问题:是否有任何“系统定义的异常 [that] 从 CLR 获得特殊处理”?有一些线程/进程状态会导致事情发生,但我看不到异常本身是特殊情况,如here 所示。显然,我必须跳一两圈才能让我的代码自己(重新)抛出ThreadAbortException,并且可能还有其他异常在抛出时会做一些有趣的事情,但这些似乎没有。 (真正的堆栈溢出和中止线程states显然确实有特殊处理。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2019-07-23
    • 2011-03-09
    相关资源
    最近更新 更多