2012-03-27 15 views
68

私はxamlベースの、Win8 CP上のC#メトロアプリケーションの内部から呼び出しています。この呼び出しは単に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); 

それはawaitでハングアップしますがHTTPコールは、実際に(シオマネキを通じて確認)ほとんどすぐに戻ります。あたかもawaitが無視され、ちょうどそこにハングアップするようです。

質問する前に - はい - プライベートネットワーク機能が有効になっています。

これがなぜハングアップするのでしょうか?

+1

どうすればその非同期メソッドを呼び出していますか?例外をスローしませんか? – svick

答えて

97

非常によく似ているように私の質問にthis answerをチェックしてください。

何か試してください:GetStreamAsync()によって返されたタスクのConfigureAwait(false)を呼び出してください。例えば。

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

ありがとうございます、これを見る前にasync/awaitをあきらめてしまいました。 – Den

+4

私も!なぜこのことがよりよく文書化されていないのですか?もう一度おねがいします –

+1

UIコンテキストとASP.NETコンテキストのどちらにも存在しないのですか? – machinarium

関連する問題