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...
- Uncomment line A (and delete the call to
Thread.ResetAbort()
in Main—another oddity) - Change line B to
throw new Exception();
- 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