繁体   English   中英

你能解释一下为什么如果我不等待异步任务就不会发现异常?

[英]Can you explain why the exception is not caught if I do not await an async task?

从我在代码上遇到的问题开始,我创建了这个简单的应用程序来重新创建问题:

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。 那么请你解释一下原因,并且peraphs给出一些避免它的黄金法则?

PS:如果在button1_Click的代码中我写的是:

Task task = Task.Run(async () =>
{
    await TestWork();
});

在第一个button1_Click实现中,您忽略了TestWork返回的Task的结果。

在您的修改版本中, await检查Exception并传播它以供您捕获。

实际上,您看到的编译器警告通常很重要。 如果TestWork实际上在不同的线程上运行了某些东西,那么因为第一个实现中的包装器Task不等待TestWork完成,所以只要TestWork启动它就会自动完成。

用这种方式写它会让它更清晰:

Task task = Task.Run( () =>
    {
        Task t = TestWork();
        // ignore t
    }
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM