2012-03-30 15 views
6

TPLで例外を処理する方法について多くのことを読んだことがありますが、実際にはわかりません。Tplで例外を処理する

このコード例みましょう:私はこれが

Catch 1 
Continuation 

を印刷することが期待しかし、私はこれは例外がまだ時に未処理とみなされることを意味し

Catch 1 
Continuation 
Wait Exception 

を取得

var task1 = new Task(() => { throw new Exception("Throw 1"); }); 
var task2 = task1.ContinueWith(t => Console.WriteLine("Catch 1:{0}", t.Exception.Message), 
           TaskContinuationOptions.OnlyOnFaulted); 
var task3 = task2.ContinueWith(t => Console.WriteLine("Continuation")); 

task1.Start(); 
try { 
    task1.Wait(); 
} 
catch (Exception ex) { 
    Console.WriteLine("Wait Exception: {0}", ex.Message); 
} 

をタスクが完了し、タスクファイナライザが最終的にアプリケーションを破棄します。

ファイナライザがスローしないように、継続内の例外をどのように処理しますか?同時に、私はタスクをフォールト状態にして、try/catchでタスクをラップすることはできません。


背景は私が指定したhereとしてではなく、エラー処理と非同期イベントパターンを実装するということです。私の完全なコードは、あなたが失敗したタスクのあなたの待機を行う。この

public IAsyncResult Begin(AsyncCallback callback, object state, Action action) { 
    var task1 = new Task(action); 
    var task2 = task1.ContinueWith(t => HandleException(t.Exception), 
            TaskContinuationOptions.OnlyOnFaulted); 
    if (callback != null) { 
     var task3 = task2.ContinueWith(t => callback(t), 
             TaskScheduler.FromCurrentSynchronizationContext()); 
     var task4 = task3.ContinueWith(t => HandleException(t.Exception), 
             TaskContinuationOptions.OnlyOnFaulted); 
    } 

    task1.Start(); 

    return task; 
} 
+0

私は、継続の試行で 't.Wait()'を呼び出し、例外を無視することを考えました。しかし、それはうまくいかないでしょう。なぜなら、他の 'Wait()'スローの後に継続が実行されるからです。 – svick

答えて

3

のように見える、とあなたはdocumentation on Task.Waitを読めば、慎重にあなたはその待ち時間が、この場合に例外を再スローされます表示されます。

しかし、あなたがtask3を待っていると、すべてが正常に動作するはずです。もちろん

あなたはこれを覚えておく必要があります。

あなたがOnlyOnFaultedオプションを使用すると、先行で 例外プロパティがnullでないことが保証されます。その プロパティを使用して例外をキャッチし、どの例外が タスクに障害を引き起こしたかを確認できます。 Exceptionプロパティにアクセスしないと、 例外が処理されません。また、キャンセルされたタスクまたは失敗したタスクのResult プロパティにアクセスしようとすると、新しい 例外が発生します。

(参考here

そして最後にまた別の良い情報源はHow to handle exceptions thrown by tasks

に私はこのことができます願っています。

+1

私はそれを得ると思います。私が.Exceptionプロパティにアクセスしても、Waitは常に例外を引き起こします。ただし、.Exceptionにアクセスすると例外が「未処理」にならないように変更され、タスクファイナライザは投げられません。クイックテストはそれを正確に確認しているようです。ありがとう – adrianm