在控制台/Windows服务应用程序中,不需要使用ConfigureAwait(false),对吗?

25

我已经使用了一段时间的 async/await,但最近深入研究并阅读了很多最佳实践提示,其中说默认情况下应始终使用 ConfigureAwait(false) 防止死锁并提高性能。

当我假定只有当前存在 SynchronizationContextTaskScheduler 时才会这样做,我想确保没有漏掉什么,这是正确的吗?

如果我有一个响应消息/命令等异步的 Windows 服务应用程序,它总是使用默认调度程序 = 可能与 awaitable 完成的线程池线程在上执行 continuation,因此无法从使用 ConfigureAwait(false) 获得死锁或性能差异,对吗?

这不像是不能放置它,但我非常讨厌嘈杂的代码...


1
最好编写模块化的代码,不关心它是否在控制台、Windows服务、ASP.NET站点或窗口项目中运行(因此,是的,您应该将其放入其中,因为您的代码可能在需要它的情况下运行),但有时您知道它不会在这些情况下使用(因此,不,您不应该将其放入其中)。这是一种编码风格问题。 - Scott Chamberlain
它实际上不应该被使用!最多只是一个hack(会使你的代码凌乱)。不要使用Wait()方法,你就没问题了。 - maracuja-juice
(and .Result aswell) - maracuja-juice
1个回答

19

一般来说,这是正确的。在控制台或服务场景下工作时,没有默认安装SynchronizationContext,因此ConfigureAwait中的continueOnCapturedContext选项将没有效果,这意味着您可以安全地删除它而不改变运行时行为。

然而,也有例外情况,因此我通常建议在适当的情况下编写您的代码,包括ConfigureAwait(false)

即使在控制台或服务应用程序中,包括此选项的主要优点是:

  1. 代码可以在以后的其他应用程序中重用。 如果您选择重用此代码,则无需跟踪由于未包括此代码而引起的错误。
  2. 如果您在运行时安装(或使用安装)SynchronizationContext,则您的方法的行为不会发生变化。

2
我认为你永远不应该使用这个,因为它最多只是一个hack,并且会显著地使你的代码混乱。"使用ConfigureAwait(false)来避免死锁最多只是一个hack)" https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html - maracuja-juice
6
你误解了那篇文章(Stephen Cleary的文章)的作者。他的意思是不要仅仅为了避免代码阻塞而使用ConfigureAwait(false)。相反,不要阻塞;在整个调用堆栈中都使用async/await来避免死锁,包括在根处。 - rory.ap
2
这正是我理解的@rory.ap。 - maracuja-juice
12
那么,你的说法“在我看来,你永远不应该使用这个”是误导性的,并没有代表你所声称你理解他文章的意思。 - rory.ap

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