2012-12-18 17 views
7

Ansyc/Awaitの「BackgroundWorker」はdesigned to be replacedです。残りのメソッドを非同期にするのを待っていますか?

Async/Awaitが凝縮しているように、私はBackgroundWorkersの一部をAsync/Await呼び出しに変換し始めています。

これは(UIから呼び出された)私が持っているコードの例です:私はRunFromTheUIを呼び出すとき

public async void RunFromTheUI() 
{ 
    await OtherAction(); 
} 

public async void OtherAction() 
{ 
    var results = await services.SomeRemoteAction(); 

    foreach (var result in results) 
    { 
     result.SemiIntenseCalculation(); 
     Several(); 
     Other(); 
     NonAsync(); 
     Calls(); 
    } 

    SomeFileIO(); 
} 

それは(非同期と待つ設計どおりに)ほとんどすぐに戻ります。

しかし、services.SomeRemoteAction()が終了した後で再開すると、foreachループが実行され、もう1つのメソッド呼び出しが実行されます。

私の質問は次のとおりです:そのループがパフォーマンスの豚であれば、UIはフリーズしますか?(バックグラウンドワーカースレッドの前にすべてがあったので、UIが遅くならなかった)。

注:私は.Net 4.0をターゲットにしており、Async Nuget Packageを使用しています。

+0

async/awaitとBackgroundWorkerは、2つの異なる問題を解決します。 BG作業者は、タスクによってより正確に置き換えられます。 Asyncはワーカーのボディコードが基本的にアイドル状態のときにのみこれらを置き換えますが、BGW/Tasksは重労働が必要なときにはまだ便利です。私はあなたの質問でサービス結果を待っているようです、ちょうどFYI。 –

+0

1.コードはコンパイルされません。あなたは '非同期void'メソッドを'待つ 'ことはできません。 2. '非同期void'メソッドの使用を避け、' await'することができず例外処理を難しくします。 – svick

答えて

6

私の質問は次のとおりです。そのループがパフォーマンスホッグであれば、UIがフリーズしますか?

はい、そうです。残りの非同期メソッドは、リモートアクションが完了したときにUIスレッドで実行されます。あなたはそれが起こるしたくない場合は、オプションは次のとおりです。

  • 使用ConfigureAwait(continueOnCapturedContext: false)継続は別のスレッドでメソッドの全体を実行し、UIスレッド
  • 上で実行されないようにTask.Runを使用して始めてください。 (まだ非同期メソッドを使用してスレッドをブロックするのを避けることができます)。

基本的には、同期呼び出し、ブロック呼び出し、またはCPU集約的な作業あなたはデフォルトであなたのためにasync/awaitの逆のUIスレッドで起こるのを避けたいと思っています。

+1

'Async'を使用している場合、' Task.Run'は 'Task.Factory.StartNew'よりも良いデフォルトを持っています。 [Stephen Toub氏の詳細はこちら](http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx) –

+0

@StephenCleary:修正しました。私は注意を払っていませんでした - 'Task.StartNew'は当然ではありません:) –

+0

Jon:async/await、taskを読んだり理解したりするのに良いスタートポイント? – shahkalpesh

関連する問題