更新:我不认为这个问题是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
但如果我做出这些改变中的任何一个......
- 取消注释 A 行(并删除 Main 中的调用
Thread.ResetAbort()
——另一个奇怪的地方) - 将 B 行更改为
throw new Exception();
- 删除 C 行
那么输出是
catch
finally
这种行为是一个错误,还是设计使然(并记录在某处)?
注意:在我的实际场景(一个 ASP.NET 应用程序)中,ThreadAbortException 由 HttpResponse.Redirect 引发,并且我在 finally 块中执行异步 I/O。