我从这里获取以下代码: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
}
}
}
答案 0 :(得分:2)
该应用似乎冻结了。用户界面没有响应。
这是一个winforms应用程序 - MDI表单应用程序。为什么与从控制台应用程序调用有什么不同?
您正在我的博客上看到我完整解释的common deadlock issue。总之,默认情况下await
将捕获"上下文"并使用它来恢复async
方法。在UI线程中,那个" context"是一个UI SynchronizationContext
,因此await
之后的代码将在该UI线程上恢复。 (在控制台应用程序中,没有"上下文",因此await
之后的代码将在线程池线程上恢复。
问题是调用代码正在调用Task.Wait()
。这将阻止 UI线程,直到Task
完成。但是,Task
表示async
方法的执行,并且该方法在UI线程空闲之前无法完成。因此,僵局。