我什么时候应该使用ConfigureAwait(true)

Ned*_*nov 27 c# asynchronous

有没有人遇到使用场景ConfigureAwait(true)?由于true是默认选项,我无法看到你什么时候使用它.

Yan*_*hof 16

是真的试图将延续编组回到捕获的原始上下文; 否则,错误.

实际上更像是说ConfigureAwait(true)使用.ContinueWith( t => {...}, TaskScheduler.FromCurrentSynchronizationContext()),ConfigureAwait(false)就像使用一样.ContinueWith( t => {...}).如果传递false,则允许继续在线程池线程上运行,而不是拉回到当前同步上下文.

  • 很好的解释,虽然这仅解释了“ConfigureAwait(true)”的作用,但没有解释**何时**有人**想要**这样做。很高兴知道一些有人想要`.ConfigureAwait(true)`的例子。这是否与根本不调用`.ConfigureAwait()`相同,或者避免使用`.ConfigureAwait()`会让代码随机使用或不使用当前上下文?例如,为什么有人在 ASP.NET MVC 应用程序中需要同步上下文? (7认同)

Dam*_*ver 9

我可以看到的一种可能性是,如果你在一个库中编写代码并且你想让你的调用者决定是否适合继续原始的上下文1(尽管我通常认为永远不会继续从原来的上下文图书馆代码)

您的调用者将传递bool参数或设置一些配置值,因此在运行时您将不知道正确的参数值是什么.


这是API的一般类型的答案,例如具有no-args变体和具有单个参数的变体,其中no-args变体被记录为"与具有众所周知的值x的单个参数变体相同" " - 如果直到运行时才知道要传递的正确值是什么,那么您应该使用正确的运行时值调用单个参数变量.


1例如,你的来电者也在提供代表.您的调用者将知道(并且可以决定)该代理是否需要返回原始上下文.

  • 这个答案完美地描述了[Polly](https://github.com/App-vNext/Polly/)库[后来采用](https://github.com/App-vNext/Polly#synchronizationcontext)的方法。一个为什么调用者可能想要在原始上下文`.ConfigureAwait(true)`上继续执行的现实示例是[如果他们使用自定义TaskScheduler](https://github.com/App-vNext/ Polly /问题/ 49)。 (2认同)
  • 这个答案建议调用“ConfigureAwait(boolVariable)”,这很好。但最初的问题是是否有充分的理由执行“ConfigureAwait(true)”,听起来答案是否定的。 (2认同)

hlo*_*dal 5

由于true是默认选项,因此我无法看到您何时使用它.

一个明显的用例是,当您想要确保每次等待某些事情时,都会明确而谨慎地选择如何处理同步上下文.

来自http://newmedialabs.co.za/blog/post/SynchronizationContexts的示例策略:

在NML中,我们更愿意总是明确说明我们希望任务继续发生的方式.因此,即使Task的默认值是ConfigureAwait(true),我们仍然会指定它,以便我们始终认识到"引擎盖下"正在发生的事情.

虽然为了提高可读性,他们使用扩展而不是ConfigureAwait(true)直接扩展:

但是,当您查看大量代码时,有些代码使用ConfigureAwait(true),有些代码使用ConfigureAwait(false),因此要找出它们的不同之处并不容易.因此我们使用ConfigureAwait(false)或有用的扩展方法ContinueOnCapturedContext().它做了同样的事情,但只是以更直观的方式将它与ConfigureAwait(false)区分开来.

  • [Eli Arbel](https://arbel.net/2014/09/21/configureawait-or-not/) 也回应了这一点:“我最近得出的结论是,最好始终在任何地方指定ConfigureAwait,以免你忘了。`,它编写了一个 Resharper 扩展来解决这个问题。 (2认同)
  • 这是回答“为什么要使用它,因为 true 是默认值”这个问题的唯一答案 (2认同)
  • 我认为应该没有默认值,调用者应该指定。许多人甚至没有意识到这甚至存在及其含义。 (2认同)