c# – 等待任务等于在ContinueWith中抛出故障任务的异常

以下不是多余的?

await blob.CopyToBlobAsync(newBlob).
       ContinueWith((t) => { if (t.IsFaulted) throw t.Exception; });

好像没有ContinueWith调用,会直接抛出异常?

何时使用continueWith而不是等待任务?

是以下相同的?

await myTask.ContinueWith(t => {'do something with the task t'});

await myTask;
'do something with the task MyTask'
最佳答案
ContinueWith(t => {if(t.IsFaulted)throw t.Exception;})行具有与直接等待CopyToBlobAsync任务不同的语义:

>它忽略了取消结果;即使CopyToBlobAsync返回的任务被取消,ContinueWith返回的任务也将成功完成.这可能是故意行为.
>它忽略了成功的结果; CopyToBlobAsync的任何返回值都将被删除.
>它通过直接抛出t.Exception来包装AggregateException中的任何异常.这几乎肯定是有缺陷的行为.

所以这并不是多余的,而且可能是一个错误.

您可以在某些情况下使用ContinueWith而不是等待任务.在我的代码中,我通常只在延续很简单的情况下执行此操作,我不需要继续中的上下文,并且我不希望异步状态机的开销.对于大多数情况,您应该更愿意等待可能与ConfigureAwait(false)结合使用.

你最后的例子不一样了;默认情况下,ContinueWith将在线程池上执行,而默认情况下等待将捕获上下文并在该上下文中执行continuation.此外,您必须非常小心如何在延续中使用任务:您通常希望将异常和取消传播到延续任务,这并不像第一次出现那么容易.

简而言之,我建议几乎在所有情况下等待.它更容易编写,更易于阅读,并具有合理的默认行为.

转载注明原文:c# – 等待任务等于在ContinueWith中抛出故障任务的异常 - 代码日志