Starting from an issue I had on my code, I’ve created this simple app to recreate the problem:
private async void button1_Click(object sender, EventArgs e)
{
Task task = Task.Run(() =>
{
TestWork();
});
try
{
await task;
MessageBox.Show("Exception uncaught!");
}
catch (Exception) { MessageBox.Show("Exception caught!"); }
}
private async void button2_Click(object sender, EventArgs e)
{
Task task = TestWork();
try
{
await task;
MessageBox.Show("Exception uncaught!");
}
catch (Exception) { MessageBox.Show("Exception caught!"); }
}
private async Task TestWork()
{
throw new Exception();
}
The code for button1_Click will not catch the exception. I’ve verified that this is because I’m not awaiting the TestWork async method. Indeed I’ve a warning message from Visual Studio that inform me I’m not awaiting the method. However the solution compile and I’m scared this can happen somewhere else in my code if I use extensively the async/await. So can you please explain the reason and peraphs give some golden rule to avoid it?
P.S.: It works if in the code for button1_Click I write:
Task task = Task.Run(async () =>
{
await TestWork();
});
In your first
button1_Clickimplementation, you are ignoring the result of theTaskreturned byTestWork.In your modified version, the
awaitchecks for an Exception and propogates it for you to catch.In fact, the compiler warning you are seeing is normally important. If
TestWorkactually ran something on a different thread, then because the wrapperTaskin your first implementation doesn’t wait forTestWorkto complete, it would just complete itself as soon asTestWorkhad started.Writing it this way makes it clearer: