In this video, I answer the question “Why is async void bad and how do I await a Task in an object constructor?”. Async void is generally considered bad for 3 reasons:
1. You can’t wait for its completion (fire and forget)
2. Any unhandled exceptions will terminate your process (can’t be caught)
3. Difficult to test (see #1 and #2) Async void methods have different error-handling semantics.
When an exception is thrown out of an async Task method, that exception is captured and placed on the Task object. With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started. However, let’s be honest, there are many areas of our code where an async void will be required. The scenario that immediately come to mind is in the constructor of an object. For example, maybe you want to load data async when your object is first created. You want to load your data async, and let the object creation process continue without blocking any threads. This is normally done with what’s called a “fire and forget” approach. Other scenarios may include the Execute method of an ICommand, or within an event handler.
Your first instinct may be to wrap these async/await calls into an “async void” method, and then just call that method in your constructor, command, or event handler. But, this is not recommended.
Luckily for use, we can use the power of a C# extension method to provide support for not only handling the completion of a Task in an async void scenario, but also handle any exceptions that may occur and provide better unit testing support.