您能否解释一下,如果我不等待异步任务,为什么不会捕获异常
本文关键字:等待 异步 任务 捕获异常 为什么不 如果 解释 一下 | 更新日期: 2023-09-27 18:36:21
从我的代码问题开始,我创建了这个简单的应用程序来重现问题:
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();
}
button1_Click
的代码不会捕获异常。我已经验证这是因为我没有等待TestWork
异步方法。事实上,我收到了来自Visual Studio的警告消息,通知我我没有等待该方法。但是,解决方案编译了,如果我广泛使用 async/await,我担心这可能会发生在我的代码中的其他地方。那么,您能否解释一下原因,并给出一些避免它的黄金法则?
PS:如果在我编写的代码中button1_Click
它有效:
Task task = Task.Run(async () =>
{
await TestWork();
});
在第一个button1_Click
实现中,您忽略了 TestWork
返回的Task
的结果。
在修改后的版本中,await
会检查异常并传播它以供捕获。
事实上,您看到的编译器警告通常很重要。如果TestWork
实际上在不同的线程上运行了某些内容,那么由于第一个实现中的包装器Task
不会等待TestWork
完成,因此它会在TestWork
启动后立即自行完成。
这样写会更清楚:
Task task = Task.Run( () =>
{
Task t = TestWork();
// ignore t
}
);