2011-07-04 66 views
37

我有一些簡單的代碼作爲攝製:等待一個任務有OnlyOnFaulted延續導致AggregateException

var taskTest = Task.Factory.StartNew(() => 
{ 
    System.Threading.Thread.Sleep(5000); 

}).ContinueWith((Task t) => 
{ 
    Console.WriteLine("ERR"); 
}, TaskContinuationOptions.OnlyOnFaulted); 

try 
{ 
    Task.WaitAll(taskTest); 
} 
catch (AggregateException ex) 
{ 
    foreach (var e in ex.InnerExceptions) 
     Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace); 
} 

然而,我卻得到了意想不到TaskCanceledException在try catch塊被拋出(它在AggregateException InnerExceptions對象)。 「任務被取消了」。

爲什麼我會得到這個異常?任務的延續永遠不會發生,它沒有產生異常,但我仍然得到了等待時的聚合異常....

我希望有人能解釋這對我有意義:)

+0

我有完全一樣的情況下,你。我認爲只是傳播上一個任務的結果會更加優雅和直觀。拋出一個TaskCanceledException是相當令人吃驚的...... – NickL

回答

53

你不等待任務一個OnlyOnFaulted延續 - 你等待那延續(返回ContinueWith)。繼續不會因爲原始任務正常返回而觸發,所以它的行爲就好像被取消一樣。

對我有意義。

我懷疑你要創建的任務,加上延續,但隨後伺候任務:

var taskTest = Task.Factory.StartNew(() => 
{ 
    System.Threading.Thread.Sleep(5000); 

}); 
taskTest.ContinueWith((Task t) => 
{ 
    Console.WriteLine("ERR"); 
}, TaskContinuationOptions.OnlyOnFaulted); 
+4

啊,好的電話......我在想ContinueWith正在返回原來的任務... – Redth

+0

很好的解釋,只是一個評論,在這種情況下,最好不要使用Factory.StartNew ()方法,因爲任務可以在繼續定義之前啓動。在這裏,我將使用新的Task()ctor,然後設置ContinueWith()並最終調用Start()方法。是否有意義? –

+1

@JorgeFioranelli:爲什麼在繼續定義之前啓動任務會出現問題?我相信TPL將會解決這個問題,不會有任何問題。 –