【问题标题】:How to set TaskContinuationOptions using async/await?如何使用 async/await 设置 TaskContinuationOptions?
【发布时间】:2013-10-31 22:54:24
【问题描述】:

我是否可以使用 async/await 来设置所有选项,例如 OnlyOnRanToCompletion、OnlyOnCanceled、NotOnFaulted 等?我找不到有关如何获得与使用任务相同的结果的示例,例如:

Task.Factory.StartNew(foo).ContinueWith(bar, TaskContinuationOptions.NotOnRanToCompletion);

我不确定简单的条件或异常处理是否可以管理显式任务中可用的所有延续行为。

【问题讨论】:

  • 你能设置位标志吗?你应该能够。 Tbh,不知道你在问什么
  • 不需要异常处理;只需使用try/catch 块,您就可以像编写代码一样编写代码,就像几乎在其他任何地方编写任何代码一样。你为什么想要改用那种风格呢?如果您想使用“OnlyOn*”或“NotOn*”选项以外的其他选项,您需要哪些选项以及为什么?
  • @natenho,如果你真的需要它,你应该可以用custom awaiter 来实现这个行为。
  • @Servy 我只是想关联特性,只是做一个练习来找出原始 TPL 代码和 elegant async/await 模式之间的转换工作和功能。基本上,问题是“我可以用更少的代码得到相同的结果吗?”。因为毕竟我们知道在这两种情况下都是 TPL 在幕后。
  • @natenho 您始终可以使用任务复制await 正在执行的操作,但并非所有可以使用显式任务完成的操作都可以使用await 完成。

标签: c# multithreading task-parallel-library async-await


【解决方案1】:

我可以使用 async/await 来拥有所有选项,例如 OnlyOnRanToCompletion、OnlyOnCanceled、NotOnFaulted 等吗?

你不需要。

await 支持非常自然的try/catch 语法,而不是使用位标志和 lambda 延续的丰富语法:

try
{
  await foo();
}
catch
{
  bar();
  throw;
}

我不确定简单的条件或异常处理是否可以管理显式任务中可用的所有延续行为。

它们自然会处理None、NotOnCanceled、NotOnFaulted、NotOnRanToCompletion、OnlyOnCanceled、OnlyOnFaulted 和 OnlyOnRanToCompletion。大多数其他标志只对并行任务有意义,而不是异步任务。例如,AttachedToParent、HideScheduler 和 PreferFairness 在 async 世界中没有意义; DenyChildAttach、LazyCancellation 和 ExecuteSynchronously 应该始终在 async 世界中指定;而LongRunning 从不应该是。

【讨论】:

  • 简单的异常处理是我对 NotOn* 的第一种方法,很高兴确认没关系。我将不得不仔细查看其他标志以查看您句子的最后一部分;)
  • 当我遇到需要指定 HideScheduler 标志的情况时,我到了这里,但我不能。场景:从 GUI 线程调用异步方法,该 GUI 线程被阻塞直到异步调用结束。这会导致死锁,因为延续会被回发到(等待和阻塞的)GUI 线程。 HideScheduler 将节省一天的时间。解决方法:new Task({async call},TaskCreationOptions.HideScheduler).Start() 并等待这个临时任务。
  • 我知道在异步调用期间阻塞 GUI 线程通常是一个糟糕的设计,但这是一个特殊的程序:主要是无头操作(想象一个备份任务),在开发期间使用 GUI 仅用于提供反馈——在生产环境中不可见/禁用/阻止。
  • 我不认为HideScheduler 做你认为它做的事情(它不会做任何事情,除非你实际上是在任务调度程序上执行任务)。有更好的选择。选项 1) 使您的 UI 异步。选项 2) 使用 Task.Run 创建任务。选项 3) 使用 ConfigureAwait(false) 避免死锁。
  • @Stephen:你说得对,我同时也意识到了。 +1 为ConfigureAwait(),我通过阅读stackoverflow.com/a/15022170 和Await, and UI, and deadlocks! Oh my! 发现了什么
【解决方案2】:

我不这么认为。

Async/await 并不是为了一起替换 TPL,而是通过使简单的操作更简洁来补充它。
如果您仍需要额外配置,则必须坚持执行任务,或者您可以尝试使用此行为实现自定义等待器。

【讨论】:

    猜你喜欢
    • 2015-09-29
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 2020-08-01
    • 2020-08-23
    • 2021-04-30
    • 2011-05-04
    相关资源
    最近更新 更多