It is theoretically possible for a framework to detect the use of async void
and wait until the async void
method returns. I describe the details in my article on SynchronizationContext
. AFAIK, ASP.NET is the only built-in framework that will wait on async void
handlers.
WPF does not have any special treatment for async void
methods. So the fact that your exit handler is completing is just coincidence. I suspect that the operations you await
are either already complete or extremely fast, which allows your handler to complete synchronously.
That said, I do not recommend the solution in the article you referenced. Instead, handle the window's Closing
event, kick off whatever asynchronous saving you need to do, and cancel the close command (and also consider hiding the window immediately). When the asynchronous operation is complete, then close the window again (and allow it to close this time). I use this pattern for doing asynchronous window-level "close" animations.
I'm unable to repro the deadlock you describe. I created a new .NET 4.5 WPF application and added an exit handler as such:
private async void Application_Exit(object sender, ExitEventArgs e)
{
await Task.Delay(1);
}
but did not observe a deadlock. In fact, even with using Task.Yield
, nothing after the await
is ever executed, which is what I would expect.