2012-03-03 25 views
5

Webサービスへの非同期呼び出しを行うメソッドがあります。そのような何か:非同期メソッドの結果を取得

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp(); 
    return await OtherClass.ProcessAsync(r); 
} 

そして、私は同期の代替を提供したい:

public static ReturnResultClass GetBasicResponse() 
{ 
    return GetBasicResponseAsync().Result; 
} 

しかし、ブロックResultコールに。非同期操作と同じスレッド上で呼び出されるためです。どうすれば結果を同期させることができますか?

ありがとうございます!

答えて

8

GUIアプリケーションの場合、asyncメソッドの継続部分は、デフォルトでUIスレッド上で実行されます。同時に、UIスレッドで同じタスクの同期待機を実行すると、デッドロックが発生します。

アプリケーションの場合は、タスクを同期して待機しないで解決できます。

ライブラリを作成している場合は、ConfigureAwait(false)を使用してこれを修正できます。この方法では、メソッドの継続部分はキャプチャされたコンテキスト(GUIアプリケーションのUIスレッド)ではなく、ThreadPoolスレッド上で実行されます。もちろん

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp().ConfigureAwait(false); 
    return await OtherClass.ProcessAsync(r).ConfigureAwait(false); 
} 

、理想的なソリューションは、彼らがしたい場合は他の人が、メソッドの同期バージョンを使用できるように、あなたのライブラリにConfigureAwait()を使用して、あなたのGUIアプリケーションで同期操作を使用しないことです。

+0

ありがとうございます! 'ConfigureAwait'は私のlibの非同期クライアントに影響しますか?つまり、非同期操作が非同期になるか、すべてのクライアントに対して他のスレッドで実行されるのでしょうか? – gor

+0

はい、非同期クライアントにも影響しますが、大丈夫です。非同期操作は非同期にとどまり、 'ConfigureAwait()'を使用するコードの継続部分はUIスレッドでは実行されません。しかし、UIスレッドから始まるメソッド内の非同期コードはそこに残ります( 'ConfigureAwait()'も使わない限り)。 – svick

関連する問題