Why is a finally block *sometimes* not executed on ThreadAbortException if it contains an await?

自作多情 提交于 2019-12-05 01:55:54

问题


UPDATE: I don't think this question is a duplicate of Can ThreadAbortException skip finally? because (1) I'm not creating another thread, so there's no possibility of a race condition, and (2) this behavior only occurs if the finally block contains an await, which that other question doesn't mention.


Consider this console program:

class Program
{
    static void Main()
    {
        try { T().GetAwaiter().GetResult(); }
        catch (ThreadAbortException) { Thread.ResetAbort(); }
        catch { }
    }

    static async Task Abort()
    {
        //await Task.Delay(1); // A
        Thread.CurrentThread.Abort(); // B
    }

    static async Task T()
    {
        try
        {
            await Abort();
        }
        catch
        {
            Console.WriteLine("catch");
            throw;
        }
        finally
        {
            Console.WriteLine("finally");
            await Task.Yield(); // C
        }
    }
}

When I compile this in Visual Studio 2015, the output is

catch

But if I make any one of these changes...

  1. Uncomment line A (and delete the call to Thread.ResetAbort() in Main—another oddity)
  2. Change line B to throw new Exception();
  3. Delete line C

then the output is

catch
finally

Is this behavior a bug, or is it by design (and documented somewhere)?

NOTE: In my actual scenario (an ASP.NET app), the ThreadAbortException is thrown by HttpResponse.Redirect, and I'm performing async I/O in the finally block.

来源:https://stackoverflow.com/questions/48215240/why-is-a-finally-block-sometimes-not-executed-on-threadabortexception-if-it-co

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!