C# 为什么不是';这个web api调用没有返回吗?

C# 为什么不是';这个web api调用没有返回吗?,c#,.net,asp.net-web-api,async-await,asp.net-web-api2,C#,.net,Asp.net Web Api,Async Await,Asp.net Web Api2,我在MVC应用程序的Global.asax中有以下方法: protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e) { SetUserRolesToSession().GetAwaiter().GetResult(); } protected async Task SetUserRolesToSession() { var networkUserIdParts = netwo

我在MVC应用程序的Global.asax中有以下方法:

protected void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
    SetUserRolesToSession().GetAwaiter().GetResult();
}

protected async Task SetUserRolesToSession()
{
    var networkUserIdParts = networkUserId.Split(new char[] { '\\' });
    var baseUrl = ConfigurationManager.AppSettings["SecurityApiBaseUrl"].ToString();
    var userSearchRequest = new UserSearchRequest
    {
        NetworkUserId = Request.LogonUserIdentity.Name
    };
    var user = (await new SecurityApiServiceWrapper(baseUrl)
        .GetUsersAsync(userSearchRequest)).FirstOrDefault();

    Session["Roles" + "_" + networkUserId] = user?.Groups.Select(x => x.Name).ToList();
}
然后,我在SecurityApiServiceWrapper中有以下代码:

public async Task<List<User>> GetUsersAsync(UserSearchRequest userSearchRequest)
{
    using (var client = GetHttpClient(_baseUrl))
    {
        var response = await client.PostAsJsonAsync("api/v1/users/search", userSearchRequest);
        if (response.IsSuccessStatusCode)
        {
            var users = await response.Content.ReadAsAsync<List<User>>();
            return users;
        }
        else //not 200
        {
        }
    }
}

public HttpClient GetHttpClient(string baseUrl)
{
    var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
    client.BaseAddress = new Uri(baseUrl);
    client.Timeout = Timeout.InfiniteTimeSpan;
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json"));
    return client;
}
公共异步任务GetUsersAsync(UserSearchRequest UserSearchRequest) { 使用(var client=GetHttpClient(_baseUrl)) { var response=wait client.PostAsJsonAsync(“api/v1/users/search”,userSearchRequest); if(响应。IsSuccessStatusCode) { var users=wait response.Content.ReadAsAsync(); 返回用户; } 否则//200 { } } } 公共HttpClient GetHttpClient(字符串baseUrl) { var client=newhttpclient(newhttpclienthandler(){usedaultcredentials=true}); client.BaseAddress=新Uri(baseUrl); client.Timeout=Timeout.InfiniteTimeSpan; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( 新的MediaTypeWithQualityHeaderValue(“应用程序/json”); 返回客户; }
当代码进入await client.PostAsJsonAsync时,进程将被卡住,永远不会返回。我可以通过Postman进行相同的api调用,响应在<1s内返回。知道问题可能是什么或如何调试吗?

SetUserRolesToSession().GetAwaiter().GetResult()
可能会导致死锁。基本上,您的
PostAsJsonAsync
延续将等待当前上下文可用的时间,但它永远不可用,因为
GetResult()
是一个阻塞调用。只需将
应用程序\u OnPostAuthenticateRequest
更改为
异步void
,然后调用
等待SetUserRolesToSession()。@GlorinOakenfoot-更改为“async void”将返回以下错误:“此时无法启动异步操作。异步操作只能在异步处理程序或模块内启动,或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保已标记该页面。此异常还可能表示有人试图调用“async void”方法,这在ASP.NET请求处理中通常不受支持。相反,异步方法应该返回一个任务,调用方应该等待它“@GlorinOakenfoot-如果我将“Application_OnPostAuthenticateRequest”的签名修改为“async Task”“那么MVC不会将其识别为事件处理程序,也不会命中。看起来答案可能是使用
EventHandlerTaskAsyncHelper
AddOnPostAuthenticateRequestAsync()
。有关更多信息,请参阅。它有点旧了,但似乎没有更好的答案。@glorin谢谢你的url。我来看看。请您提供更多关于您在第一篇文章中描述的根本原因的解释,或者提供一个好的url,让我对这种行为有更多的了解。基本上,我从代码中删除了GetResult(),代码没有锁定。当然,我没有得到完整的答复,但我想更好地了解GetWaiter()的细节。GetResult()b/c我知道它在某些情况下对我很有效,但我不认为我很了解为什么它在某些情况下对我不起作用