2016-06-01 84 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

你正在綁定你的continuations錯誤。

除了向「主」任務添加三個連續,您還將繼續添加到延續。當主要任務完成而沒有錯誤時,OnlyOnFaulted延續被取消,這會觸發OnlyOnCanceled延續,您錯誤地連線到OnlyOnFaulted延續而不是主要任務。然後最好的部分 - 這意味着第二次連續完成正確,並且由於您在第二次連續中連接了上一次連續,所以最後的連續也會運行,因此完整輸出爲「任務已取消,任務已完成」。 :)

儘管如此,你期待什麼是正確的輸出並不明顯。爲什麼你首先使用延續? await可以爲您處理比您手動完成的更好的事情。混合awaitContinueWith很少是一個好主意:)你是否想要await的主要任務(失敗時,拋出異常)?還是其中一個延續?或者僅僅是OnlyOnRanToCompletion延續(這就是你現在正在做的事情,它永遠不會按照你期望的方式工作)?如果這個延續永遠沒有機會運行會怎麼樣?

相關問題