2016-12-12 14 views
0

なぜSynchronizationContext.Currentがnullの場合にTask.Wait()とTask.Resultを呼び出すのが100%安全でないのですか?SynchronizationContext.Currentがnullの場合、Task.Waitを安全に使用できますか?

私はマルチスレッドで同期サービスを提供しています。同期メソッドの1つをHttpClient.PostAsXmlAsyncの呼び出しで置き換えます。実装は.Resultを使用して同期メソッドに変換し、プロジェクト全体の変更を防ぎます。しかし、私たちはよく文書化されている典型的なデッドロックの問題を抱えています。

同期コンテキストがないとデッドロックが発生する可能性があります。

+0

おそらく少なくともいくつかのコードを投稿することができます。サービスとは、Windowsサービスを意味しますか? – Evk

+0

@エヴァーク - おそらくWebサービスを意味する – Zegar

+0

なぜ非同期メソッドを最初に使用しているのですか?同期操作を実行する場合は、最初から本質的に同期メソッドを使用してください。とにかく待つつもりなら、いくつかのメソッドを非同期にする目的はありません。どちらか、またはサービスハンドラを非同期にするだけです。 – Servy

答えて

-1

方法HttpClient.PostAsXmlAsyncは、バックグラウンドでHttpClient.SendAsyncを実行する拡張方法です。 SendAsyncメソッドは非同期メソッドです。
非同期メソッドを「同期」方法で呼び出すと、あなた自身が気づいたように非常にうまく文書化されたデッドロックにつながります。 asyncを使用していない - asyncにアプリケーション全体のパイプラインを変えないようにするには プロジェクト全体に

を変更することを避けるために、同期メソッドの中にそれを変換する

...。
async-await始めるそれを使用する場合、すべてのアプリケーションに広がっゾンビウイルスです:)

+0

「同期コンテキストを作成する方法」とはどういう意味ですか?私は待っている*が文脈をキャプチャすると信じています。私はSendAsyncを認識していないか、同期コンテキストを作成する*を待っています。 –

0

全く同期コンテキストが存在しない場合は、非同期コードのtypical problems with blockingが発生しません。ただし、100%安全ではありません。スレッドがスレッドプールに属している場合、ブロッキングによってスレッドがプールに戻らないため、スレッドプールスレッドが不足する可能性があります。

私の場合、この問題は実際には社内のプロキシサーバーによって発生していました。十分な時間が与えられれば、スレッドは本当に戻ってくるでしょう。私はHttpClientにHttpClientHandlerを渡して、UseProxy = falseを渡すようにコードを変更し、問題は解決しました。

関連する問題