等待的任务不能优雅地处理异常

时间:2014-02-12 16:37:04

标签: c# exception async-await

我希望我可以使用这种模式:

var task = Task.Run(() => Agent.GetUserType(Instance));
await task;
string information = task.GetExceptionOrStatus(); // extension method

当我的sql服务器没有启动时 - 就像一个测试用例 - 我看到WCF服务抛出的异常没有被任务优雅地处理,我得到:
类型' System.ServiceModel.FaultException'的例外情况发生在Microsoft.Threading.Tasks.dll但未在用户代码中处理。
我的印象是我的代码能够从任务对象中提取错误。

我该怎样做得更好?

3 个答案:

答案 0 :(得分:6)

await将按设计传播该任务的任何例外情况。

var task = Task.Run(() => Agent.GetUserType(Instance));
try
{
  await task;
}
catch (Exception ex)
{
  // TODO
}
string information = task.GetExceptionOrStatus(); // extension method

答案 1 :(得分:2)

如果您不希望await投掷,则可以根据之前的Task创建一个永不失败的新Task。类似的东西:

static async Task<T> IgnoreException<T>(this Task<T> task)
{
    try
    {
        return await task;
    }
    catch
    {
        return default(T);
    }
}

替代实施:

static Task<T> IgnoreException<T>(this Task<T> task)
{
    return task.ContinueWith(t => t.Exception == null ? t.Result : default(T));
}

用法则如下所示:

await task.IgnoreException();
string information = task.GetExceptionOrStatus(); // extension method

答案 2 :(得分:1)

您应该在try / catch块中包围await task;。如果出现Exception,则会抛出AggregateException,其中包含Task内发生的所有异常。