c# - ThreadAbortException 最后能跳过吗?

标签 c# multithreading abort finally

我读过的所有内容都声称线程中止将在从 ThreadAbortException 结束之前执行 finally block 。我想确认这一点,这样我就可以计划如何处理一些可以无限期挂起的第三方代码。但是以下测试让我感到困惑:

public void runTest(DateTime deadline)
{
    testThread = new Thread(() => 
    {
        try 
        {
            Console.WriteLine("test thread started at " + DateTime.Now.ToShortTimeString());
            while (true) { }
        }
        finally
        {
            Console.WriteLine("test thread entered FINALLY at " + DateTime.Now.ToShortTimeString());
            while (true) { }
        }
    });
    testThread.Start();
    while (testThread.IsAlive && deadline.Subtract(DateTime.Now).TotalSeconds > 0)
    {
        Console.WriteLine("main thread while loop " + DateTime.Now.ToShortTimeString());
        Thread.Sleep(10000);
    }
    if (testThread.IsAlive)
        testThread.Abort();
    Console.WriteLine("main thread after abort call " + DateTime.Now.ToShortTimeString());
}

运行时我发现控制台从未提及进入 finally block 。应用程序在 .abort 调用之后继续运行,就好像根本没有 finally block 一样。难道我做错了什么?在到达控制台的最终写入之前,不应该将控制权传递给 finally block ,或者执行顺序是否仍然取决于 finally 在单独的线程中或其他什么?

最佳答案

Docs say : ThreadAbortException 是一个可以捕获的特殊异常,但它会在 catch block 的末尾自动再次引发。引发此异常时,运行时会在结束线程之前执行所有 finally block 。因为线程可以在 finally block 中进行无限计算或调用 Thread.ResetAbort 来取消中止,所以不能保证线程永远结束。

我很确定您的线程正在被转储,因为您退出该方法并丢失了对它的引用,因此它被垃圾收集器收集。尝试使 testThread 变量成为该类的字段成员,看看会发生什么。

那,或者你有一个竞争条件,因为线程是并行运行的:主线程在启动的测试线程可以输出最终数据之前完成(异常是昂贵的并且需要时间来到达 catch 或 finally 阻塞)。

关于c# - ThreadAbortException 最后能跳过吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18002668/

相关文章:

c# - (SQL)替换 DataGridView 中的 NULL 值的有效方法?

c# - c#中new关键字隐藏成员的有效应用

c# - Interlocked.CompareExchange 是否使用内存屏障?

java - 多线程编程中的公平性是什么?

wcf - 在 IClientChannel 代理上调用 Abort() 会抛出异常吗?

c# - VisualStateManager.GoToState 不适用于 DataTemplate

c# - 带有包含字典的参数的 Api Controller 中的 JSON.Net 始终为空

c++ - 多线程环境中的静态局部变量初始化

c# - 如果 abort() 不起作用,强制关闭 'rogue' 线程

linux - 中止信号的一般原因有哪些?