2012-03-27 57 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