Task.Run()不会引发异常?

时间:2018-11-16 18:14:42

标签: c# winforms

我在

中有以下代码
private void Button_Click(object sender, EventArgs e)
{
    try
    {
        Task.Run(async () => await Presenter.Search());
    }
    catch (Exception ex)
    {
        LabelMessage.Text = "Error:....";
    }
}

在某些情况下,函数Presenter.Search()可能会出现异常,我想显示一条错误消息。但是,异常不是引发吗?我只能在Visual Studio调试器中看到它。

2 个答案:

答案 0 :(得分:4)

确实应该这样写:

private async void Button_Click(object sender, EventArgs e)
{
    try
    {
        await Presenter.Search();
    }
    catch (Exception ex)
    {
        LabelMessage.Text = "Error:....";
    }
}

现在等待呼叫,并且可以正确处理异常。请注意,出于列出here的原因,通常不应该使用async void,但是对于UI事件处理程序,则推荐使用这种方法。

答案 1 :(得分:2)

首先,如果Presenter.Search已经返回了Task,则应考虑制作事件处理程序async并简单地放入

await Presenter.Search();

在try-catch块中。

Task.Run(Func<Task>)存在重载的原因是,您可以强制调度已经存在的Task在池线程上执行。在极少数情况下可以证明这种情况是合理的,因为通常您应该依靠Task返回方法的内部实现。但是,如果您知道异步方法不使用线程(例如,仅返回一个Task,它将在特定事件上完成),并且您对在池线程上强制执行有足够的信心,那么您可以这样做这样。但是,在这种情况下,您还应该等待外部任务。否则,通话即被抛弃,您将一无所获:

await Task.Run(() => Presenter.Search());

请注意,我省略了内部的async-await:

await Task.Run(async () => await Presenter.Search());

这也将起作用,并且在功能上与以前的版本等效,但是在执行的任务链中增加了不必要的内部状态机。

TL; DR:不知道任何更多细节,await Presenter.Search();似乎是更好的解决方案,但如果您知道自己在做什么,也可以证明await Task.Run(() => Presenter.Search());是合理的。