2016-06-01 14 views
2

以下のコードでawait RunAsync();を呼び出すと、TaskContinuationOptions.OnlyRanToCompletionの継続を続行することが期待されますが、OnlyOnCanceled継続が呼び出されます(デバッグ出力「タスクがキャンセルされました」)。OnlyOnCanceled継続がなぜ呼び出されるのですか?

なぜですか?

private static async Task RunAsync() 
{ 
    try 
    { 
     await Task.Run(() => DoWork()) 
      .ContinueWith(
       (t) => 
       { 
        if (t?.Exception != null) 
        { 
         throw t.Exception; 
        } 
       }, TaskContinuationOptions.OnlyOnFaulted 
      ).ContinueWith(
       (t) => 
       { 
        Debug.WriteLine("Task canceled."); 
       }, TaskContinuationOptions.OnlyOnCanceled 
      ).ContinueWith(
       (t) => 
       { 
        Debug.WriteLine("Task completed."); 
       }, TaskContinuationOptions.OnlyOnRanToCompletion); 

    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine(ex.Message); 
    } 
} 

private static void DoWork() 
{ 
    Thread.Sleep(1000); 

} 

答えて

4

あなたの継続を間違ってバインドしています。

「メイン」タスクに3つの継続を追加するのではなく、継続への継続に継続を追加します。メインタスクがエラーなしで終了すると、OnlyOnFaulted継続が取り消され、OnlyOnCanceled続行がメインタスクではなくOnlyOnFaulted続行に間違って接続されます。最後に、2番目の継続が正しく終了したことを意味し、2番目の継続で最後の継続を配線してから、最終的な継続も同様に実行されるので、完全な出力は「タスクがキャンセルされました。 :)

正しい出力であるとは思わないでしょう。なぜあなたは最初に継続を使用していますか? awaitは、手動で行うよりはるかにうまく処理できます。 awaitContinueWithを混ぜることはめったに良い考えではありません:) awaitメインタスク(例外がスローされたときに失敗します)にしようとしていますか?または継続の1つ?または、ちょうどOnlyOnRanToCompletion継続(これはあなたが今やっていることです、そして、それがあなたがそれが働くことを期待するように決して働くつもりはありません)?その継続が決して実行する機会を得られない場合、どうなるでしょうか?

関連する問題