【问题标题】:ConfigureAwait(false) in WebAPI controllerWebAPI 控制器中的 ConfigureAwait(false)
【发布时间】:2016-02-08 08:50:46
【问题描述】:

SonarLint 是否应该在 ASP.NET Web API 控制器中触发 S3216?似乎这条规则是针对桌面应用程序的,在 ASP.NET 中上下文完全不同,没有死锁的危险。还是我错过了什么?

【问题讨论】:

    标签: c# async-await asp.net-web-api2 sonarlint


    【解决方案1】:

    当您不需要捕获上下文时,仍应在 WebAPI 中使用 ConfigureAwait(false)

    ConfigureAwait 控制是否在捕获的SynchronizationContext 上恢复。确实,这在 UI 应用程序中是一个更痛苦的问题,但它在任何地方都有相关性,因为 SynchronizationContext 是所有 UI 应用程序和所有 asp.net 应用程序。

    在 UI 应用程序中,SynchronizationContext 管理的资源是单个 UI 线程,因此如果您阻止它,您可能会死锁。在 asp.net 应用程序中,资源是请求上下文,您也可以对其进行死锁。

    您可以避免在控制台应用程序或 Windows 服务中使用 ConfigureAwait,但在适当的情况下继续使用它仍然是一个好习惯。

    【讨论】:

    • 但是:“如果在需要上下文的方法中有 await 之后的代码,则不应使用 ConfigureAwait。[...] 对于 ASP.NET 应用程序,这包括任何使用 HttpContext 的代码。当前或构建 ASP.NET 响应,包括控制器操作中的返回语句。” (来自here)。我的理解是,是的,在库中您应该始终使用ConfigureAwait(false),但在 GUI 代码或控制器中,这取决于您在等待之后所做的事情。
    • @VictorGrigoriu 当然。如果您需要上下文(在 UI 或 asp.net 中),那么让 await 捕获它。只有在不需要上下文时才需要ConfigureAwait(false),但不管是“桌面应用”还是 WebAPI 应用。
    • 我的意思是,SonarLint 不应将此标记为 Web API 控制器方法中的违规行为,因为它取决于。
    • @VictorGrigoriu 我不知道 SonarLint 是什么。但它会标记 UI 应用程序.. 没有理由不应该用于网络应用程序。
    • 这是一种建立在 Roslyn 之上的 FxCop。
    【解决方案2】:

    @VictorGrigoriu,我们只检查编译单元的输出类型是否为 DLL,我们仅报告 DLL 中的问题。您是对的,我们报告了在 DLL 中仍需要切换回原始上下文的情况。一般来说,这是一件很难弄清楚的事情,但我们可以添加对顶级 Web 应用程序集的检查。我们需要想出一个好的方法来做到这一点,或者默认禁用规则以不产生误报。

    我创建了一张票来跟踪这个问题:https://jira.sonarsource.com/browse/SLVS-790

    在我们提出永久解决方案之前的其他选项:如果您觉得这很烦人,您可以在给定项目上本地禁用此规则。为此,您需要通过“references/analyzers/open active rule set”编辑项目的规则集文件

    【讨论】:

    • 感谢您的调查!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多