在WebApi或MVC控制器中使用ConfigureAwait(false)是否有任何危险?

时间:2016-10-23 01:57:57

标签: c# .net asp.net-mvc asynchronous asp.net-web-api

假设我有两种情况:

1)WebApi控制器

    [System.Web.Http.HttpPost]
    [System.Web.Http.AllowAnonymous]
    [Route("api/registerMobile")]
    public async Task<HttpResponseMessage> RegisterMobile(RegisterModel model)
    {
        var registerResponse = await AuthUtilities.RegisterUserAsync(model, _userService, User);
        if (registerResponse.Success) {
            var response = await _userService.GetAuthViewModelAsync(model.Username, User);
            return Request.CreateResponse(HttpStatusCode.OK, new ApiResponseDto() { Success = true, Data = response });
        }
        else {
            return Request.CreateResponse(HttpStatusCode.OK, registerResponse);
        }

    }

2)MVC控制器

    [Route("public")]
    public async Task<ActionResult> Public()
    {
        if (User.Identity.IsAuthenticated)
        {
            var model = await _userService.GetAuthViewModelAsync(User.Identity.Name);
            return View("~/Views/Home/Index.cshtml", model);
        }
        else
        {
            var model = await _userService.GetAuthViewModelAsync(null);
            return View("~/Views/Home/Index.cshtml", model);
        }
    }

我一直在阅读我应该使用ConfigureAwait的时候,似乎我应该在所有与UI无关的异步调用上使用ConfigureAwait(false)。我不知道这意味着什么......我应该在.ConfigureAwait(false)所有await来电中使用THREE.SPRITE吗?

我正在寻找一些关于何时应该使用它的明确指南。

这个问题与Best practice to call ConfigureAwait for all server-side code不一样 - 我在WebApi和MVC的上下文中寻找关于此方法的用例的直截了当的答案,而不是一般的C#。

4 个答案:

答案 0 :(得分:46)

  

似乎我应该在所有不直接绑定到UI的异步调用上使用ConfigureAwait(false)。

不完全。该指南在这里没有意义,因为没有UI线程。

传递给ConfigureAwait的参数是continueOnCapturedContext,这更清楚地解释了该方案。只要ConfigureAwait(false)方法的其余部分取决于当前上下文,您就希望使用async

在ASP.NET 4.x中,&#34; context&#34;是请求上下文,其中包括HttpContext.Current和文化等内容。另外 - 这是未记录的部分 - 很多ASP.NET辅助方法取决于请求上下文。

(旁注:ASP.NET Core不再具有&#34; context&#34;)

  

我应该在所有上述await调用中使用.ConfigureAwait(false)吗?

我还没有听到任何有关此问题的确切指导,但我怀疑它没问题。

在我自己的代码中,我从不在控制器操作方法中使用ConfigureAwait(false),因此它们已在请求上下文中完成。这对我来说似乎更合适。

答案 1 :(得分:0)

如果ASP.NET Core应用程序中没有实际的上下文,则将.ConfigureAwait(false)添加到控制器的等待方法中不会有任何危害。

但是,如果由于某种原因最终将来有机会在ASP.NET 4中考虑类似上下文的情况,那就完全不同了。我们不能冒着在不同上下文中运行的风险,除非我们对此不加任何大意(在这种情况下,我们可以使用任何可用的线程进行处理,从而可能会提高性能)。

我在这里的选择是即使不使用它也要添加ConfigureAwait(false)。

答案 2 :(得分:-3)

在控制器中使用ConfigureAwait(false)对我来说听起来不太好,因为它将使主线程等待操作完成。我发现最好的方法是在您的“服务/业务”层和“持久性”层中使用它。

答案 3 :(得分:-4)

您可以在公共操作 MVC控制器上使用 ConfigureAwait ,如果您的 _userService.GetAuthViewModelAsync 一直等待,它有助于防止交易锁定。 如果异步服务保持等待,则云会引发死锁,可能会阻止UI的httpcontext。

请查看以下链接以了解此案例:

http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html