应用应从 LoginUser()接收 httpresponsemessage ,但它没有响应。
private void button1_Click(object sender, EventArgs e)
{
if (LoginUser(tUser.Text, Password.Text).Result.IsSuccessStatusCode)
{
Notifier.Notify("Successfully logged in.. Please wait!");
}
else
{
Notifier.Notify("Please check your Credential..");
}
}
public async Task<HttpResponseMessage> LoginUser(string userid, string password)
{
string URI = "http://api.danubeco.com/api/userapps/authenticate";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("c291cmF2OmtheWFs");
using (var response = await client.GetAsync(String.Format("{0}/{1}/{2}", URI, userid, password)))
{
return response;
}
}
}
请帮忙!
答案 0 :(得分:6)
您正在阻止UI线程并导致死锁。 From Stephen Cleary's blog(只需使用GetJsonAsync
方法替换LoginUser
,GetStringAsync
替换为client.GetAsync
):
所以这就是从顶级方法开始的情况 (Button1_Click for UI / MyController.Get for ASP.NET):
顶级方法调用GetJsonAsync(在UI / ASP.NET上下文中)。
GetJsonAsync通过调用HttpClient.GetStringAsync(仍在上下文中)启动REST请求。
GetStringAsync返回未完成的任务,表示REST请求未完成。
GetJsonAsync等待GetStringAsync返回的任务。捕获上下文并将用于继续运行 GetJsonAsync方法稍后。 GetJsonAsync返回未完成的任务, 表示GetJsonAsync方法未完成。
顶级方法同步阻止GetJsonAsync返回的任务。这会阻止上下文线程。
...最终,REST请求将完成。这样就完成了GetStringAsync返回的任务。
GetJsonAsync的延续现在已准备好运行,它等待上下文可用,以便它可以在上下文中执行。
- 醇>
死锁。顶级方法是阻塞上下文线程,等待GetJsonAsync完成,GetJsonAsync正在等待 上下文是免费的,所以它可以完成。
简单易用的解决方案(也来自博客):
- 在“库”异步方法中,尽可能使用ConfigureAwait(false)。
- 不要阻止任务;一直使用async。
醇>
第二个解决方案建议您将button1_Click
更改为:
private async void button1_Click(object sender, EventArgs e)
{
if ((await LoginUser(tUser.Text, Password.Text)).IsSuccessStatusCode)
{
Notifier.Notify("Successfully logged in.. Please wait!");
}
else
{
Notifier.Notify("Please check your Credential..");
}
}