110

C#Win8 CP 上の xamlベースのメトロ アプリケーション内から呼び出しを行っています。この呼び出しは単に Web サービスをヒットし、JSON データを返します。

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が無視され、そこにぶら下がっているかのようです。

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

これがハングする理由はありますか?

4

3 に答える 3

162

非常に似ているように見える私の質問に対するこの回答を確認してください。

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

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

これが役立つかどうかは、上記のコードがどのように呼び出されているかによって異なります。私の場合、asyncを使用してメソッドを呼び出すとTask.GetAwaiter().GetResult()、コードがハングします。

これはGetResult()、タスクが完了するまで現在のスレッドをブロックするためです。タスクが完了すると、タスクが開始されたスレッドコンテキストに再び入ることを試みますが、そのコンテキストにはすでにスレッドがあり、GetResult()...デッドロックの呼び出しによってブロックされているためできません。

このMSDNの投稿では、.NETが並列スレッドを同期する方法について少し詳しく説明しています。私自身の質問に対する回答は、いくつかのベストプラクティスを示しています。

于 2012-04-29T02:39:17.337 に答える