如何使用async/await设置TaskContinuationOptions?

5

使用async/await可以获得像OnlyOnRanToCompletion、OnlyOnCanceled、NotOnFaulted等所有选项吗?我找不到如何实现与使用Tasks相同结果的示例:

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

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


你能设置位标志吗?你应该可以的。说实话,我不确定你在问什么。 - Lews Therin
2
对于异常处理,这并不是必需的;只需使用 try/catch 块,您就可以像在任何其他代码中一样编写代码。为什么你会想要使用那种风格呢?如果你想使用除了 "OnlyOn*" 或 "NotOn*" 选项之外的东西,你需要什么以及为什么? - Servy
@natenho,如果你真的需要,你应该能够使用自定义等待器来实现这种行为。 - noseratio - open to work
@Servy 我只是想将功能进行对应,只是为了练习,找出原始TPL代码和“优雅”的async/await模式之间的转换工作量和能力。基本上,问题是“我可以用更少的代码获得相同的结果吗?”因为毕竟,我们知道在两种情况下都是TPL在后台运行。 - natenho
1
@natenho,您可以始终使用任务来复制await所做的事情,但并不是所有可以通过显式任务完成的操作都可以使用await完成。 - Servy
2个回答

12

我能否使用async/await获得像OnlyOnRanToCompletion、OnlyOnCanceled、NotOnFaulted等所有选项?

你不需要这样做。

与使用位标志和lambda延续的繁琐语法不同,await支持非常自然的try/catch语法:

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

我不确定简单的条件语句或异常处理是否能够处理显式任务中所有可用的继续行为。

它们自然地处理NoneNotOnCanceledNotOnFaultedNotOnRanToCompletionOnlyOnCanceledOnlyOnFaultedOnlyOnRanToCompletion。大多数其他标志仅对并行任务有意义,而不是异步任务。例如,AttachedToParentHideSchedulerPreferFairnessasync世界中没有意义;DenyChildAttachLazyCancellationExecuteSynchronously应始终在async世界中指定;而LongRunning从不应该。


简单的异常处理是我对NotOn*的第一种方法,可以确认这是可行的。我需要仔细查看其他标志来审查你句子的最后部分 ;) - natenho
我遇到了一个需要指定“HideScheduler”标志但无法实现的情况,于是来到了这里。场景如下:从GUI线程调用异步方法,该GUI线程会一直阻塞,直到异步调用结束。由于继续操作被发送回(等待和阻塞的)GUI线程,因此会导致死锁。使用HideScheduler可以解决这个问题。解决方法:使用“new Task({async call},TaskCreationOptions.HideScheduler).Start()”创建一个临时任务并等待它。 - robert4
我知道通常在异步调用期间阻塞GUI线程是一个不好的设计,但这是一个特殊的程序:主要是无界面操作(比如备份任务),在开发过程中只用GUI来提供反馈 -- 在生产环境中是不可见/禁用/阻塞的。 - robert4
1
我认为 HideScheduler 并不是你想象中的那样(除非你正在实际执行任务调度器上的任务,否则它什么也不做)。有更好的选择。选项1)使您的UI异步。选项2)使用 Task.Run 创建任务。选项3)使用 ConfigureAwait(false) 避免死锁。 - Stephen Cleary
@Stephen:你说得对,我也在此期间意识到了这一点。ConfigureAwait()值得一试,我是通过阅读stackoverflow.com/a/15022170Await, and UI, and deadlocks! Oh my!这两篇文章发现的。+1 - robert4

0

我不这么认为。

Async/await并不是完全取代TPL,而是通过使简单操作更加清晰来补充它。
如果您仍然需要额外的配置,您将不得不坚持使用任务,或者尝试实现具有此行为的自定义awaiter。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接