C# 在WebApi或MVC控制器中使用ConfigureWait(false)是否存在任何危险?

C# 在WebApi或MVC控制器中使用ConfigureWait(false)是否存在任何危险?,c#,.net,asp.net-mvc,asynchronous,asp.net-web-api,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 = awai

假设我有两种情况:

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);
        }

    }
    [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);
        }
    }
[System.Web.Http.HttpPost]
[System.Web.Http.AllowAnonymous]
[路由(“api/注册移动”)]
公共异步任务RegisterMobile(RegisterModel模型)
{
var registerResponse=wait AuthUtilities.registerUserSync(model,_userService,User);
if(registerResponse.Success){
var response=await\u userService.GetAuthViewModelAsync(model.Username,User);
return Request.CreateResponse(HttpStatusCode.OK,new-apiressedto(){Success=true,Data=response});
}
否则{
return Request.CreateResponse(HttpStatusCode.OK,registerResponse);
}
}
2)MVC控制器

    [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);
        }

    }
    [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);
        }
    }
[路线(“公共”)]

公共异步任务-我正在WebApi和MVC环境中寻找此方法用例的简单答案,而不是一般的C#。

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

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

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

不完全是。这条准则在这里没有意义,因为没有UI线程

传递给
ConfigureAwait
的参数是
continueOnCapturedContext
,它更清楚地解释了该场景。只要
async
方法的其余部分不依赖于当前上下文,就需要使用
ConfigureAwait(false)

在ASP.NET 4.x中,“上下文”是请求上下文,包括
HttpContext.Current
和区域性等内容。此外,许多ASP.NET帮助程序方法确实依赖于请求上下文,这是未记录的部分

(旁注:ASP.NET核心不再具有“上下文”)

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

我没有听到任何关于这方面的明确指导,但我怀疑这是可以的


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

在控制器中使用
ConfigureAwait(false)
听起来不太好,因为它会使主线程等待操作完成。我想最好的办法是在服务/业务层和持久性层中使用它。

如果ASP.NET核心应用程序中没有实际的上下文,那么将.ConfigureAwait(false)添加到控制器中的等待方法中应该是无害的

然而,如果将来有机会,不管出于什么原因,像在ASP.NET4中一样,需要考虑上下文,那将是一个不同的故事。我们不能冒险在不同的上下文中运行,除非我们对此毫不在意(在这种情况下,我们可以使用任何可用的线程进行处理,从而可能提高性能)


我在这里的选择是添加ConfigureAwait(false),即使它没有被使用。

@MickyD读到这一点,我看到“/”当在GUI或ASP.NET上下文中调用时,此方法会导致死锁。“-WebApi和MVC不是在利用.NET上下文吗?“在上面的场景中,你会做什么?为什么?”米基德我已经读了好几遍了,但仍然不清楚。我一定很傻。“ASP.NET中的makes是指该线程在恢复该方法时是否进入请求上下文。”-在上述场景中是否需要执行此操作?-我不可能是唯一一个从基于示例的简单回答中获益的人。。。请不要标记为关闭,因为这个问题更倾向于API和MVC,而不是通用C。读一读会更有趣。。。另一方面,如果您/您的团队非常有纪律,并且从不使用全局值(如当前Http上下文或当前文化),则无论哪种方式都可以。这也是您正在寻找的答案-不太清楚您的问题有什么不同(或者为什么您希望得到除服务器端代码中的-no point to call
ConfigureAwait(false)
“no point to call ConfigureAwait(false)”之外的任何其他答案)<。没有任何直接的、基于示例的答案的相互冲突的指导。这里不是有一个规模问题吗,在长时间运行的API调用上释放UI线程来服务更多的请求?ConfigureAwait(false)操作将在下一个可用线程上继续,而不是保留发出请求的线程。虽然每个请求的性能没有提高,但规模有了提高,允许完成更多的请求,而不是从有限的线程池中占用线程的长时间运行任务。对此有任何更新吗?我正在用asp.net核心mvc编写控制器代码,想知道使用/不使用
ConfigureAwait(false)
会有什么影响。你的旁注没有真正的帮助-如果ASP.NET核心没有上下文,这是否意味着我应该使用
ConfigureAwait(false)
?@DavidClarke:因为没有上下文,
ConfigureAwait(false)
没有效果。更多信息:@StephenCleary谢谢,这是一个非常有用的参考。有没有办法找到哪些ASP.NET方法依赖于上下文?@Landerah:据我所知,没有。即使可以,它也是一个可以随下一个版本更改的实现细节。在这一点上,这其实并不重要,因为ASP.NET核心是未来的核心。ConfigureAwait(false)不会禁用异步await!它只是意味着当所述异步m