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

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

您可以使用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 } 

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

 public static Task SwallowExceptions(this Task task) { return task.ContinueWith(_ => { }); } faultedTask.SwallowExceptions().Wait(); if (faultedTask.IsFaulted) { // handle exception } 

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

 public static Task SwallowExceptions(this Task task) { return task.ContinueWith(completedTask => completedTask.IsFaulted ? default(T) : completedTask.Result); } 

不幸的是,此function不是内置的。 使用此解决方法:

  myTask.ContinueWith(_ => { }, TaskCOntonuationOptions.ExecuteSynchronously).Wait(); 

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

根据您所写的内容,可能会捕获exception并检查IsFaulted属性是否为您的解决方案? IsFaulted

在Task中捕获exception并将其返回到结果中?

 var task1 = Task.Factory.StartNew(() => { try { throw new MyCustomException("I'm bad, but not too bad!"); } catch(Exception ex) { return new Result { Error = ex }; } });