I'm trying to figure out why my console app is not torn down by an unhandled task exception. All I do is create a task where I immediately throw an exception. Finally I force GC. In the first example I have a handler for the TaskScheduler.UnobservedTaskException
event and I can see the exception get handled.
static async Task ThrowsException()
{
Console.WriteLine("Throwing!");
throw new Exception("Test exception");
}
static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
ThrowsException();
Console.WriteLine("Collecting garbage.");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Done collecting garbage.");
Console.ReadKey();
}
static void TaskScheduler_UnobservedTaskException(object sender,
UnobservedTaskExceptionEventArgs e)
{
Console.WriteLine("Unobserved task exception occured in finalizer.");
Console.WriteLine(e.Exception.InnerException.Message);
}
Output:
Throwing!
Collecting garbage.
Unobserved task exception occured in finalizer.
Test exception
Done collecting garbage.
But if I comment out the line TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException
the program still runs to completion. In this case the output is:
Throwing!
Collecting garbage.
Done collecting garbage.
Why doesn't the application crash in this case?
Not crashing the program from a unobserved task exception was a change that was made for .NET 4.5, see the remarks section of the MSDN for the event. If you want your program to have the pre .NET 4.5 behavior and cause it to crash you need to put in your app.config
<configuration>
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
</configuration>
This will bring back the old behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With