问题
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();
});
回答1:
In your first button1_Click
implementation, you are ignoring the result of the Task
returned by TestWork
.
In your modified version, the await
checks for an Exception and propogates it for you to catch.
In fact, the compiler warning you are seeing is normally important. If TestWork
actually ran something on a different thread, then because the wrapper Task
in your first implementation doesn't wait for TestWork
to complete, it would just complete itself as soon as TestWork
had started.
Writing it this way makes it clearer:
Task task = Task.Run( () =>
{
Task t = TestWork();
// ignore t
}
);
来源:https://stackoverflow.com/questions/10895484/can-you-explain-why-the-exception-is-not-caught-if-i-do-not-await-an-async-task