2011-02-10 6 views
5

最初の部分が失敗した場合、タスクが続行されないようにしようとしています。Task.ContinueWith例外を防止する

私のコードは以下のようになります。

Task listener = Task.Factory.StartNew(openConnection).ContinueWith((t) => listenForNumber()); 

    void openConnection() 
    { 
     try 
     { 
      //stuff 
     } 
     catch 
     { 
      //morestuff 
     } 
    } 

    void listenForNumber() 
    { 
     //even more stuff 
    } 

今listenForNuberは()OpenConnectionメソッドは、()catchブロック

を入力した場合、私は、任意のヘルプをContinueWith((t) => listenForNumber(),TaskContinuationOptions.NotOnFaulted);

しかし、誰成功を試しに実行すべきではありません? :(

おかげ

+3

キャッチブロック内の例外を再スローまたはスワローできますか? –

答えて

8

TaskContiuationOptions.NotOnFaultedあなたの方法に障害が発生していない限り、何の効果も、その実行中にスローされた例外が未処理すなわちました。

あなたのcatchブロックで

、あなたは例外を再スローする必要がありません明らかになります(あなたの作業を実行した後にthrow;ステートメントを使用してスタックトレースを保存します(何らかのクリーンアップがあるかもしれません)。そうでない場合、例外は再びスローされないため、メソッドは「フォールト」とみなされません。

+0

しかし、私は例外を再現すればどこでそれを飲み込むのに最適な場所なのでしょうか?そうすれば、ユーザーコードによって処理されないAggregatedExeptionや例外はありませんか?最初のキャッチブロックですべてが既に行われているので、もう一度処理する必要はありません。 – Ekoms

+0

@Ekoms:私が知る限り、AggregateExceptionは、タスクの 'Result'プロパティにアクセスしている場合にのみスローされます。それはあなたが例外を飲み込むことができるときの1つの場所でなければなりませんが、まずは予期せぬ例外ではなく、本当にあなたが飲み込もうとしている例外であるかどうかを調べるべきです。 – ShdNx

1

あなたのタスクメソッドに例外をスローする必要があります.TP Lは例外をキャッチしない限り、メソッドが失敗したことを知らない。

フォールトケースの継続方法が必要です。これは、例外を記録する簡単な方法です。

例外の継続方法がない場合は、タスクメソッドが例外をスローしたときにアプリケーションで未処理の例外が発生します。

2

拡張メソッドヘルパーを作成します。

public static void PropagateExceptions(this Task task) 
{ 
    if (task == null) 
     throw new ArgumentNullException("task"); 
    if (!task.IsCompleted) 
     throw new InvalidOperationException("The task has not completed yet."); 

    if (task.IsFaulted) 
     task.Wait(); 
} 

次に、コードを実行する前に拡張メソッドPropagateExceptions()を呼び出します。タスクがキャンセルされた場合、PropagateExceptions()メソッドも再スローされます。

t1.ContinueWith(t => { 
    t.PropagateExceptions(); 
    listenForNumber(); 
}); 
関連する問題