Unfortunately, that example will never show you your code. The UnobservedTaskException
will only happen if a Task gets collected by the GC with an exception unobserved – as long as you hold a reference to task1
and task2
, the GC will never collect, and you’ll never see your exception handler.
In order to see the behavior of the UnobservedTaskException
in action, I’d try the following (contrived example):
public static void Main()
{
TaskScheduler.UnobservedTaskException
+=
(object? sender, UnobservedTaskExceptionEventArgs eventArgs) =>
{
eventArgs.SetObserved();
((AggregateException)eventArgs.Exception).Handle(ex =>
{
Console.WriteLine("Exception type: {0}", ex.GetType());
return true;
});
};
StartTasks();
Thread.Sleep(100);
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("Done");
Console.ReadKey();
}
private static void StartTasks()
{
Task.Factory.StartNew(() => { throw new ArgumentNullException(); });
Task.Factory.StartNew(() => { throw new ArgumentOutOfRangeException(); });
}
This will show you your messages. The first Thread.Sleep(100)
call provides enough time for the tasks to throw. The collect and wait forces a GC collection, which will fire your event handler 2x.