C# 为什么不是';这个web api调用没有返回吗?
我在MVC应用程序的Global.asax中有以下方法: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
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我知道它在某些情况下对我很有效,但我不认为我很了解为什么它在某些情况下对我不起作用