c# - 等待任务等于在 ContinueWith 中抛出错误任务的异常

标签 c# async-await

下面是不是多余的?

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; }) 行与 await CopyToBlobAsync 具有不同的语义 直接任务:

  • 它忽略取消结果;即使 CopyToBlobAsync 返回的 Task 被取消,ContinueWith 返回的 Task 也会成功完成。这可能是故意行为。
  • 它忽略了成功的结果;来自 CopyToBlobAsync 的任何返回值都将被丢弃。
  • 它通过直接抛出 t.Exception 将任何异常包装在 AggregateException 中。这几乎可以肯定是错误行为。

所以它完全不是多余的,可能是个错误。

在某些情况下,您可以使用 ContinueWith 而不是 await 任务。在我的代码中,我通常只在 continuation 很简单的情况下才这样做,我不需要 continuation 中的上下文,并且我不想要 async 状态机的开销。对于大多数情况,您应该更喜欢 await 可能与 ConfigureAwait(false) 结合使用。

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

简而言之,我几乎在所有场景中都推荐await。它更易于编写、更易于阅读,并且具有合理的默认行为。

关于c# - 等待任务等于在 ContinueWith 中抛出错误任务的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16142945/

相关文章:

c# - 为什么单个循环会导致内存泄漏?

c# - 在 .NET 中使用 S3 存储

python - 使用 asyncio 同时执行两个函数

python - asyncio/aiohttp - 如何进行一系列异步 - 但依赖 - 请求?

c# - C#中基于任务的异步方法的超时模式

c# - PictureBox 工具提示更改 C#

c# - 为什么即使我释放/处置位图,我也会收到 OutOfMemoryException?

c# - Mysql .NET 3.5 上的 TypeLoad 异常

c# - 控制台应用程序中的正确异步循环

javascript - 使用异步等待的 REST API 调用