如何知道为什么HttpClient调用不会返回?

时间:2016-06-14 19:57:36

标签: c# asp.net .net rest

我从这里获取以下代码:http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("http://localhost:9000/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // New code:
    HttpResponseMessage response = await client.GetAsync("api/products/1");
    if (response.IsSuccessStatusCode)
    {
        Product product = await response.Content.ReadAsAsync>Product>();
        Console.WriteLine("{0}\t${1}\t{2}", product.Name, product.Price, product.Category);
    }
}

我已将BaseAddress和标题网址部分更新为我的。完整的URL通过浏览器按预期工作。

当我使用下面的代码时,会调用并从Web API应用程序返回。我可以看到这一点,因为Web API应用程序正在调试模式下运行。但是在这一行之后调用者方面没有任何事情发生:

HttpResponseMessage response = await client.GetAsync("api/products/1");

该应用似乎冻结了。用户界面没有响应。我确实在try / catch块中有这个代码,但它没有遇到异常。

有没有办法找出正在发生的事情?

应用程序的调用方式如下:

class Program
{
    static void Main()
    {
        RunAsync().Wait();
    }

    static async Task RunAsync()
    {
        using (var client = new HttpClient())
        {
            // TODO - Send HTTP requests
        }
    }
}

1 个答案:

答案 0 :(得分:2)

  

该应用似乎冻结了。用户界面没有响应。

     

这是一个winforms应用程序 - MDI表单应用程序。为什么与从控制台应用程序调用有什么不同?

您正在我的博客上看到我完整解释的common deadlock issue。总之,默认情况下await将捕获"上下文"并使用它来恢复async方法。在UI线程中,那个" context"是一个UI SynchronizationContext,因此await之后的代码将在该UI线程上恢复。 (在控制台应用程序中,没有"上下文",因此await之后的代码将在线程池线程上恢复。

问题是调用代码正在调用Task.Wait()。这将阻止 UI线程,直到Task完成。但是,Task表示async方法的执行,并且该方法在UI线程空闲之前无法完成。因此,僵局。