有没有办法在没有抛出异常的情况下等待TPL任务?

Jul*_*rch 8 .net c# exception-handling task-parallel-library

我们中的一些人更喜欢以异常轻的方式编码.但是,如果您等待任务并行库任务,并且任务引发了异常,它也会在调用线程上引发异常.有没有(最好是标准的)方法来避免这种行为,只是在你找回异常时检查异常的响应?

Iva*_*oev 12

你可以使用Task.WaitAny:

        var task = Task.Run(() =>
        {
            // ...
            throw new Exception("Blah");
        });
        Task.WaitAny(task);
        if (task.IsFaulted)
        {
            var error = task.Exception;
            // ...
        }
        else if (task.IsCanceled)
        {
            // ...
        }
        else
        {
            // Success
        }
Run Code Online (Sandbox Code Playgroud)


boo*_*ife 5

不幸的是,此功能不是内置的.使用此解决方法:

 myTask.ContinueWith(_ => { }, TaskCOntonuationOptions.ExecuteSynchronously).Wait();
Run Code Online (Sandbox Code Playgroud)

您可以将其转换为扩展方法.

  • @Gusdor你是什么意思?它完全符合OP的要求.等待任务而不抛出异常. (3认同)
  • 你能解释为什么这个解决方案解决了这个问题吗? (2认同)

i3a*_*non 5

您不能在没有引发异常的情况下等待故障任务.但是您可以等待继续执行该任务,该任务仅在原始任务完成后才完成,而不会引发异常:

public static Task SwallowExceptions(this Task task)
{
    return task.ContinueWith(_ => { });
}

faultedTask.SwallowExceptions().Wait();
if (faultedTask.IsFaulted)
{
    // handle exception
}
Run Code Online (Sandbox Code Playgroud)

如果您的任务返回一个值,您可以在extensions方法中表示该值,如果没有异常则返回实际值,如果有,则返回默认值:

public static Task<T> SwallowExceptions<T>(this Task<T> task)
{
    return task.ContinueWith(completedTask => 
        completedTask.IsFaulted 
            ? default(T) 
            : completedTask.Result);
}
Run Code Online (Sandbox Code Playgroud)