在 .NET 中使用 ConfigureAwait

You*_*f13 6 .net c# asynchronous async-await configureawait

我在很多地方都读过 ConfigureAwait(包括 SO 问题),以下是我的结论:

  • ConfigureAwait(true):在与运行 await 之前的代码相同的线程上运行其余代码。
  • ConfigureAwait(false):在运行等待代码的同一线程上运行其余代码。
  • 如果 await 后跟访问 UI 的代码,则任务应附加.ConfigureAwait(true). 否则,由于另一个线程访问 UI 元素,将发生 InvalidOperationException。

我的问题是:

  1. 我的结论正确吗?
  2. ConfigureAwait(false) 什么时候可以提高性能,什么时候不能?
  3. 如果为 GUI 应用程序编写,但下一行不访问 UI 元素。我应该使用 ConfigureAwait(false) 还是 ConfigureAwait(true) ?

Gab*_*uci 8

要更直接地回答您的问题:

ConfigureAwait(true):在与运行 await 之前的代码相同的线程上运行其余代码。

不一定是同一个线程,而是同一个同步上下文。同步上下文可以决定如何运行代码。在 UI 应用程序中,它将是同一个线程。在 ASP.NET 中,它可能不是同一个线程,但您将拥有HttpContext可用的,就像您以前所做的那样。

ConfigureAwait(false):在运行等待代码的同一线程上运行其余代码。

这是不正确的。ConfigureAwait(false)告诉它不需要上下文,所以代码可以在任何地方运行。它可以是运行它的任何线程。

如果 await 后跟访问 UI 的代码,则任务应附加.ConfigureAwait(true). 否则,由于另一个线程访问 UI 元素,将发生 InvalidOperationException。

它“应该附加.ConfigureAwait(true)”是不正确的。ConfigureAwait(true)是默认值。所以如果这是你想要的,你不需要指定它。

  1. ConfigureAwait(false) 什么时候可以提高性能,什么时候不能?

返回到同步上下文可能需要一些时间,因为它可能必须等待其他东西完成运行。实际上,这种情况很少发生,或者等待时间太短以至于您永远不会注意到。

  1. 如果为 GUI 应用程序编写,但下一行不访问 UI 元素。我应该使用 ConfigureAwait(false) 还是 ConfigureAwait(true) ?

可以使用ConfigureAwait(false),但我建议您不要使用,原因如下:

  1. 我怀疑您会注意到任何性能改进。
  2. 它可以引入您可能意想不到的并行性。如果使用ConfigureAwait(false),则延续可以在任何线程上运行,因此如果您正在访问非线程安全对象,则可能会遇到问题。这些问题并不常见,但可能会发生。
  3. 您(或其他维护此代码的人)可能会添加稍后与 UI 交互的代码,并且会引发异常。希望ConfigureAwait(false)很容易发现(它可能采用与抛出异常的方法不同的方法)并且您/他们知道它的作用。

我发现根本不使用更容易ConfigureAwait(false)(图书馆除外)。在ConfigureAwait 常见问题解答中用 Stephen Toub(微软员工)的话来说:

在编写应用程序时,您通常需要默认行为(这就是为什么它是默认行为)。

  • @TheodorZoulias 嘿!我很惊讶你注意到了。我一直在潜伏,但过去的一年很忙碌,压力很大,所以我没有花时间回答任何问题。 (2认同)