Async Wandering Part 7 — Exceptions on unobserved tasks

This is the seventh part of the Async Wandering series. For your convenience you can find other parts in the table of contents in Part 1 – Why creating Form from WinForms in unit tests breaks async?

Let’s take this code:

It doesn’t print any exception because we don’t await the task. Can we do something about it?

Let’s use the UnobservedTaskException handler:

You can now verify that it prints out the exception correctly after you press enter. When GC notices there is a task with an exception on it, it handles it and calls the delegate.

But! If you take a look at Task source it has no finalizer. How does it work?

If you decompile async method, you can see this:

So there is some SetException method. It creates a TaskExceptionHolder under the hood. That type has a finalizer and does the following:

So it calls the handler.