GetAsync:不返回HttpResponseMessage

Rya*_*ala 1 c# asynchronous async-await webapi2 httpresponsemessage

应用程序应该从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..");
        }            
    }
Run Code Online (Sandbox Code Playgroud)
    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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

请帮忙!

sha*_*y__ 6

您正在阻止UI线程并导致死锁.从斯蒂芬·克利里的博客(只需更换GetJsonAsync你的LoginUser方法,并GetStringAsyncclient.GetAsync):

所以这就是发生的事情,从顶级方法开始(用于ASP.NET的UI/MyController.Get的Button1_Click):

  1. 顶级方法调用GetJsonAsync(在UI/ASP.NET上下文中).

  2. GetJsonAsync通过调用HttpClient.GetStringAsync(仍在上下文中)启动REST请求.

  3. GetStringAsync返回未完成的Task,表示REST请求未完成.

  4. GetJsonAsync等待GetStringAsync返回的任务.捕获上下文,稍后将用于继续运行GetJsonAsync方法.GetJsonAsync返回未完成的Task,表示GetJsonAsync方法未完成.

  5. 顶级方法同步阻止GetJsonAsync返回的任务.这会阻止上下文线程.

  6. ...最终,REST请求将完成.这样就完成了GetStringAsync返回的任务.

  7. GetJsonAsync的延续现在可以运行了,它等待上下文可用,以便它可以在上下文中执行.

  8. 僵局.顶级方法是阻塞上下文线程,等待GetJsonAsync完成,GetJsonAsync正在等待上下文空闲,以便它可以完成.

简单的可用解决方案(也来自博客):

  1. 在"库"异步方法中,尽可能使用ConfigureAwait(false).
  2. 不要阻止任务; 一直使用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..");
    }            
}
Run Code Online (Sandbox Code Playgroud)