8

上記のトピックについて多くの質問がありますが、これは新しい質問を保証するのに十分に異なると私は考えています。私は次のようなものを持っています。Status; TaskStatus.RanToCompletion,TaskStatus.CanceledおよびもちろんAggregateExceptionからTaskStatus.Faultedを介して。何それから - コードがTPLと例外処理

Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
    asyncMethod(uiScheduler, token, someBoolean), token); 

asyncTask.ContinueWith(task => 
{ 
    // Check task status. 
    switch (task.Status) 
    { 
     // Handle any exceptions to prevent UnobservedTaskException.    
     case TaskStatus.RanToCompletion: 
      if (asyncTask.Result) 
      { 
       // Do stuff... 
      } 
      break; 
     case TaskStatus.Faulted: 
      if (task.Exception != null) 
       mainForm.progressRightLabelText = task.Exception.InnerException.Message; 
      else 
       mainForm.progressRightLabelText = "Operation failed!"; 
     default: 
      break; 
    } 
} 

このように見えるすべてがうまく動作しますが、継続の中から投げ出されるAggregateExceptionの可能性があるように私は、私はこの権利をやっているかどうか心配ですか?

私はWaitに私のasyncTaskを置いておきたいと思いません。これはUIスレッドへの復帰を妨げるでしょう。続き内からスローされた例外は、私がこのような何かをしなければならないというわけではありませできキャッチするために確実に

Task parentTask = Task.Factory.startNew(() => 
    { 
     Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
      asyncMethod(uiScheduler, token, someBoolean), token); 

     Task continueTask = asyncTask.ContinueWith(task => 
      { 
       // My continuation stuff... 
      } 

     try 
     { 
      continueTask.Wait(); 
     } 
     catch(AggregateException aggEx) 
     { 
      // Some handling here... 
     } 
    }); 

これでも動作しますか?ここでベストプラクティスは何ですか?

いつもありがとうございました。

+0

私は実際に彼らはAggregateExceptionを投げたとき「完成に走った」という作業を見てきました。この種のエラー処理は機能しません。どうしてトライ/キャッチを使ってみませんか? –

+0

バックグラウンドスレッドまたは実際の継続デリゲートメソッドで呼び出されたメソッドを意味しますか? – MoonKnight

答えて

12

。後者のアプローチでは、きれいなタスクワークフローを定義することができます。たとえば:

Task myRootTask = ....; 

myRootTask.ContinueWith(rootAntecdent => 
{ 
    // this will only be executed if the antecedent completed successfully, no need to check for faults 
}, 
TaskContinuationOptions.OnlyOnRanToCompletion); 

myRootTask.ContinueWith(rootAntecedent => 
{ 
    // this will only be executed if the antecedent faulted, observe exception and handle accordingly 
}, 
TaskContinuationOptions.OnlyOnFaulted); 
2

MSDNはかなりよく「どのように」件名に書かれています:here

あなたは、彼らは単に、彼らがae.Handle(lambda)で処理し、アプリの停止を作成する方法を知っている例外をフィルタリングし、try/catch(AggregateException)ブロックを使用気づくでしょうハンドルが残っていない部分がある場合。

あなた あなたが先行詞が TaskContinuationOptions.OnlyOnFaultedオプションを使用して、障害が発生した場合にのみ、これまで実行されます、特定の継続にチェーンをすることができます AggregateExceptionを監視したり、代表者の中に伝統のtry/catchを使用することができます
+0

私はあなたのリンクが提供するもののような例を認識しています。私の問題は、継承代理人全体をtry catchで囲むことなく、継承からスローされたexeptionsを処理する方法です。次にこれが唯一の方法かもしれません。マイクロソフトのおもちゃのコードのベストプラクティスではなく、実世界のコードのための最良の要素を知りたい。乾杯。 – MoonKnight

+0

リンクの+1。非常に便利です – SleepyBoBos

+0

OPはWaitを使用せずにこれを行う方法を知りたいです。すべての例はタスク待ちです。この[http://msdn.microsoft.com/en-us/library/dd997415.aspx]リンクを試してください。 –