2

应用程序应该从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;
            }
        }
    }

请帮忙!

4

1 回答 1

7

您正在阻塞 UI 线程并导致死锁。来自 Stephen Cleary 的博客(只需替换GetJsonAsync为您的LoginUser方法,并GetStringAsync替换为client.GetAsync):

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

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

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

  3. GetStringAsync 返回未完成的任务,表示 REST 请求未完成。

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

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

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

  7. GetJsonAsync 的延续现在已准备好运行,它等待上下文可用,以便可以在上下文中执行。

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

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

  1. 在您的“库”异步方法中,尽可能使用 ConfigureAwait(false)。
  2. 不要阻塞任务;一直使用异步。

第二种解决方案建议您更改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..");
    }            
}
于 2016-03-16T11:11:16.437 回答