与ASP.NET Core相关的ConfigureAwait(false)?


100

我在GitHub上偶然发现了一个问题(https://github.com/HTBox/allReady/issues/1313),他们ConfigureAwait(false)ASP.NET Core中讨论了删除代码的问题,并声称

的呼叫ConfigureAwait(false)是多余的,无济于事

我在这里能找到的最好的答案是“旁注”(来自Stephen Cleary,https: //stackoverflow.com/a/40220190/2805831 ),它告诉我们

ASP.NET Core不再具有“上下文”

因此,ConfigureAwait(false)ASP.NET Core中(即使使用完整的.Net Framework)真的没有必要吗?在某些情况下,它在性能上是否有任何真正的收获?结果/语义上是否有所不同?

编辑:如果我将其托管为控制台应用程序或IIS,在这方面是否有所不同?


2
这取决于您打算在哪里使用它。如果您想直接在ASP.NET Core应用程序中使用它,那么不用,您不必调用它(您不必在iirc的ASP.NET旧版中调用它)。但是,如果您编写了一个库,则应该始终使用 ConfigureAwait(false),因为该库可以由不同的应用程序使用(ASP.NET Core,WPF,UWP,控制台等)
Tseng

1
默认情况下,ASP.NET Core作为控制台应用程序运行,并且AFAIK控制台应用程序没有SynchronizationContext,因此,对于默认的ASP.NET Core应用程序,即使使用完整的Framework,这听起来也很合理。
乔·怀特

@JoeWhite好,编辑了问题。如果我的ASP.NET Core应用程序在IIS中会有所不同吗?
佩德罗·洛伦兹

3
在IIS中运行的ASP.NET Core应用程序仍作为控制台应用程序运行-唯一的区别是IIS正在启动和关闭应用程序实例(与在托管ASP.NET Worker进程实例中的方式相同)经典ASP.NET)。它不会更改ASP.NET应用程序内任何与线程相关的行为。(我指定的“默认”的唯一原因是,你可以,例如,主机ASP.NET核心一个GUI应用程序里面,在这种情况下,你不得不考虑同步内容。)
乔·怀特

注意ConfigureAwait(false),尽管 ASP.NET classic 相关,但绝不是必需的。这是一个折衷方案:它可以缓解一些异步同步死锁(无论如何都是设计缺陷-除非有人做一些蠢事,否则它们不存在),并且由于不重新加载上下文而使性能提高了约微秒。以无法依赖上下文为代价,并且无法ConfigureAwait遍历代码。 stackoverflow.com/questions/28221508/...
达克斯Fohl

Answers:


105

ConfigureAwait仅对在SynchronizationContextASP.NET Core不具备的上下文中运行的代码有影响(ASP.NET“传统”具有)。

通用代码仍应使用它,因为它可能与一起运行SynchronizationContext

ASP.NET Core SynchronizationContext


17
只是想稍微说明一下,非核心环境中的ASP.NET确实具有同步上下文,而ASP.NET核心没有。
斯科特·张伯伦

@Morgado,即使该应用程序托管在IIS中也是如此吗?
Pedro Lorentz

7
IIS中未托管ASP.NET Core应用程序。IIS只是充当反向代理。
Paulo Morgado

2
我已经用Stephen Cleary的最新帖子更新了答案。但是,是的,ASP.NET Core是ASP.NET Core。
Paulo Morgado

14
@NamNgo。赞赏这是一个古老的帖子,但是Stephen Cleary在Paulo上面链接的帖子中的一个问题中对此做了澄清。“由框架(确定ASP.NET Core而不是ASP.NET Classic)确定SynchronizationContext,而不是运行时(确定.NET Core而不是.NET 4.6.2)”
Gavin Sutherland

14

那这个呢?

目前(2020年2月),MS Blog上的开发人员建议使用ConfigureAwait(false)以提高性能,避免死锁。 https://devblogs.microsoft.com/dotnet/configureawait-faq/

我听说.NET Core中不再需要ConfigureAwait(false)。真正?假。在.NET Core上运行时需要它,其原因与在.NET Framework上运行时完全相同。在这方面没有任何改变。


如果某些用户代码(或您的应用程序正在使用的其他库代码)设置了自定义上下文并调用了您的代码,或者在预定给自定义TaskScheduler的Task中调用了您的代码,那么即使在ASP.NET Core中,您可能会看到非默认上下文或调度程序,它将导致您想要使用ConfigureAwait(false)。当然,在这种情况下,如果避免同步阻塞(无论如何都应避免在Web应用程序中进行阻塞),并且如果您不介意在这种有限的情况下降低性能开销,则可能无需使用ConfigureAwait(false)就可以摆脱困境。
Alisson

1
据此,我会说大多数情况下是不需要的。除非您使用自定义同步上下文或使用这样做的库。
Alisson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.