2012-03-27 134 views
68

我正在Win8 CP上基于xaml的C# metro应用程序进行调用;这个调用只是点击一个Web服务并返回JSON数据。在HttpClient中等待的异步调用永不返回

HttpMessageHandler handler = new HttpClientHandler(); 

HttpClient httpClient = new HttpClient(handler); 
httpClient.BaseAddress = new Uri("http://192.168.1.101/api/"); 

var result = await httpClient.GetStreamAsync("weeklyplan"); 
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WeeklyPlanData[])); 
return (WeeklyPlanData[])ser.ReadObject(result); 

它挂在awaitHTTP调用实际上返回几乎立即(通过小提琴手确认);就好像await被忽略,它只是挂在那里。

在你问之前 - 是 - 专用网络功能已打开。

任何想法,为什么这会挂?

+1

你是怎么调用'async'方法的?它不抛出异常吗? – svick 2012-03-27 18:57:39

回答

97

检查出this answer我的问题似乎非常相似。

需要尝试的事情:致电ConfigureAwait(false)关于由GetStreamAsync()返回的任务。例如。

var result = await httpClient.GetStreamAsync("weeklyplan") 
          .ConfigureAwait(continueOnCapturedContext:false); 

不管这是不是有用取决于如何你上面的代码被称为 - 在我的情况下调用使用Task.GetAwaiter().GetResult()导致代码挂async方法。

这是因为GetResult()会阻止当前线程,直到任务完成。当任务完成时,它尝试重新进入它启动的线程上下文,但不能,因为在该上下文中已经有一个线程,它被GetResult()的调用阻塞... 死锁!

This MSDN post详细介绍了.NET如何同步并行线程 - the answer given to my own question给出了一些最佳实践。

+7

谢谢,在看到这个之前几乎放弃了异步/等待。 – Den 2013-08-29 16:32:31

+4

我也是!为什么没有更好的文件记录?再次感谢 – 2014-11-02 16:30:48

+1

如果它不在UI上下文和ASP.NET上下文中,它会发生吗? – machinarium 2015-12-24 09:32:19