2015-12-31 71 views
11

私のプロジェクトのベストプラクティスを見つけようとしています。これは、アイテムのリストを表示するUIを持つ典型的なWPFアプリケーションであり、結果を返すデータサービスがあります。Async await vs GetAwaiter()。GetResult()とコールバック

UIをブロックしないようにサービスを非同期に呼び出しています。私たちは、私たちの前にある2つのオプションがあります:サーバーへのHTTP呼び出しを行うクライアント側(

非同期を使用して
  1. これはボタンからすべてのメソッド非同期のマーキング要求するキーワード を待つの層にサービスを提供するためにすべての方法をクリックし、クラス)とその間の任意のメソッド。このアプローチはどこでも非同期伝播の問題以外はうまく動作します

  2. このアプローチでは、UIクライアントはサービスレイヤを呼び出し、コールバックをサービスレイヤに渡します。サービスレイヤはhttpコールをサーバーをタスク内に置き、GetAwaiter()。GetResult()を使用して、http呼び出しが終了すると、UIクライアントから渡されたコールバックを呼び出します。この場合、メソッドは非同期とマークする必要はありませんが、GetAwaiter()の使用については実際にはわかりません。

    Task.Run(async()=> // httpコール、invoke callback).GetAwaiter()。GetResult );

私はより良いアプローチであるかを調べることを試みていると私は

+1

私は、第2のアプローチがデッドロックになることは間違いないと確信しています。私は、Windows Universalを使って開発するときに何かに直面していたからです。 – Felype

+0

例外の問題もあります。私は完全な非同期実装で、最後に 'AggregateException'を取得しますが、' GetAwaiter'メソッドで何が起こるのか分かりません。 – Eris

+0

@Erisあなたが待っているときは、 'AggregateException'を取得しません。内部例外が発生します。 'GetResult'でも同じことが起こります。 – i3arnon

答えて

16

に注意する必要がありますアプローチのいずれかでいくつかの問題がある場合は、asyncawaitキーワードのすべての方法を使用する必要があります、または非同期をまったく使用しないでください。

2番目のオプションは実際には非同期ではありません。これは、非同期操作を呼び出して、task.GetAwaiter().GetResult()と同時にそれをブロックしています。 非常に複雑ですが、非同期ではなく、デッドロックにつながる可能性があります。

+0

デッドロックの原因となる背景情報がありますか?私もこれを経験しましたが、なぜこれが起こるのか、どういう仕組みになっているのか、さらに詳細な情報を探しています。 –

+2

@FrederikGheysels http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – i3arnon

+0

Azure Active Directory(TokenCache)のこのAPIに悩まされていることを除いて、大きなアドバイスが好きです。同期動作が必要です。 'BeforeAccessNotification'からキャッシュを読み込み、キャッシュを書き込むまで「AfterAccessNotification」から戻ることはできません。あなたがsyncrhous APIを余儀なくされ、ファイルにアクセスする必要があるときあなたの助言は何ですか? –

関連する問題