4

更新:我不认为这个问题是Can ThreadAbortException finally skip 的重复?因为(1)我没有创建另一个线程,所以不可能出现竞争条件,并且(2)这种行为只有在finally块包含时才会发生await,其他问题没有提到。


考虑这个控制台程序:

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
        }
    }
}

当我在 Visual Studio 2015 中编译它时,输出是

catch

但如果我做出这些改变中的任何一个......

  1. 取消注释 A 行(并删除 Main 中的调用Thread.ResetAbort()——另一个奇怪的地方)
  2. 将 B 行更改为throw new Exception();
  3. 删除 C 行

那么输出是

catch
finally

这种行为是一个错误,还是设计使然(并记录在某处)?

注意:在我的实际场景(一个 ASP.NET 应用程序)中,ThreadAbortException 由 HttpResponse.Redirect 引发,并且我在 finally 块中执行异步 I/O。

4

0 回答 0