ThreadAbortException可以最终跳过吗? [英] Can ThreadAbortException skip finally?

查看:73
本文介绍了ThreadAbortException可以最终跳过吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Everything I've read claims an abort on a thread will execute the finally block before ending from a ThreadAbortException. I wanted to confirm this so I can plan on how to handle some 3rd party code that can hang indefinitely. However the following test has me confused:

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块. .abort调用后,应用程序继续运行,好像根本没有finally块一样.难道我做错了什么?

What I find when running this is that console never mentions entering the finally block. The application continues on after the .abort call as if there is no finally block at all. Am I doing something wrong? Shouldn't control pass to the finally block before reaching the final write to console or is the execution order still a function of the fact that the finally is in a separate thread or something?

推荐答案

Docs say: ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block. When this exception is raised, the runtime executes all the finally blocks before ending the thread. Because the thread can do an unbounded computation in the finally blocks or call Thread.ResetAbort to cancel the abort, there is no guarantee that the thread will ever end.

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

I'm pretty sure your thread is being dumped because you exit the method and lose a reference to it, and so it gets collected by the Garbage Collector. Try making the testThread variable a field member of the class and see what happens.

那,或者由于线程并行运行而使您处于竞争状态:主线程在加速测试线程可以输出final数据之前就已经完成了(异常代价很高,需要花费一些时间才能到达catch或finally块).

That, or you have a race condition since the threads run in parallel: the main thread is finishing before the spun-up test thread can output the finally data (Exceptions are expensive and take time to reach catch or finally blocks).

这篇关于ThreadAbortException可以最终跳过吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆