Reputation: 53
In my App.xaml.cs
, I have created a handler for responding to the AppDomain.CurrentDomain.UnhandledException event.
Inside the handler, I need to call an asynchronous method which sends an email report about the error. So I'm awaiting the method, and inside it I'm awaiting Net.Mail.SmtpClient.SendMailAsync().
But this doesn't work -- when the control reaches the second await (right before the actual sending), the application exits.
When I get rid of all async and use the synchronous alternative, Net.Mail.SmtpClient.Send(), the email gets sent correctly.
It seems no other exceptions are being thrown inside the handler. Also, it doesn't seem to be just a Visual Studio debugging mode problem.
Is it not possible to successfully call asynchronous methods inside the UnhandledException handler?
Update:
The signature of my handler method looks like this:
private async void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e);
and I attach the handler to the event in the constructor of App
like this:
App()
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
Upvotes: 1
Views: 359
Reputation: 41008
Events are always void
. That means that if you want to use await
, you must use async void
. That's causing the problem you see here.
When await
acts on an incomplete Task
, the rest of the method is scheduled for completion after waiting, and it returns. Usually it returns a Task
that the caller can await, but since the return type is void
, it returns nothing. The caller cannot await it, even if it wanted to. Usually this isn't an issue with events, since events are just a notification that "something" happened and whatever triggered the event isn't dependent on anything that's happening inside the event handler.
But in this case, the framework moves on with shutting down the application after the event handler returns. So since await
returns, the application shuts down without waiting for the task to actually complete.
Your best solution is to keep everything synchronous in your event handler. This will prevent it from returning before you expect it to.
And by "keep everything synchronous", I mean actually use synchronous methods (like Net.Mail.SmtpClient.Send()
). Don't wait synchronously on asynchronous methods, since that can cause deadlocks.
Upvotes: 3