2015-04-14 54 views
2

我有一大堆任務的定義爲:任務WhenAll使用

Task t1 = new Task(() => { /* Do Something */ }); 
Task t2 = new Task(() => { /* Do Something */ }); 
Task t3 = new Task(() => { /* Do Something */ }); 
Task t4 = new Task(() => { /* Do Something */ }); 

List<Task> allTasks = new List<Task>(); 
allTasks.Add(t1); 
allTasks.Add(t2); etc. 

然後終於:

Task.WhenAll(allTasks).ContinueWith((t) => 
{ 
    MyBlockingCollection.CompleteAdding(); 
}); 

foreach (Task t in allTasks) 
{ 
    t.Start(); 
} 

我有關上述代碼的問題:

這是正確的方法利用任務?

Task.WhenAll()本身是否啓動任務,或者我們是否必須明確啓動它們。如果是這樣,我們首先開始,然後做Task.WhenALL()

我還需要爲這些任務做異常處理,請您提出處理任務內異常的正確方法。理想情況下,我希望任務在發生異常時將一些診斷信息寫入文本文檔。

我對Tasks界有點新鮮感,感謝您的幫助!

+0

這似乎是關於什麼時候開始任務的問題,可以通過簡單地運行代碼來解決。關於異常處理的 – XenoPuTtSs

+0

雖然我不太確定,但是在處理任務時發生異常的情況下,確實有'State'屬性集'Faulted'。 –

+1

如果您是Tasks的新手,那麼我強烈建議您閱讀其中一篇(如果不是_the_)關於此主題的最佳文章:https://msdn.microsoft.com/en-us/magazine/jj991977.aspx 。它是由[@Stephen Cleary](http://stackoverflow.com/users/263693/stephen-cleary)編寫的 – ken2k

回答

2

是否Task.WhenAll()自行啓動任務,或者我們必須 明確啓動它們。如果是這樣,我們先開始然後做 Task.WhenAll()?

您需要先單獨開始每個任務,等待

,我需要做的異常處理這些任務以及..

每個任務都被獨立的執行單元,所以異常處理髮生在其範圍內。這意味着您可以做的是從任務中返回一個異常,作爲結果。主線程將讀取一個結果並且行爲適當。

+0

如果我在try catch中包裝了Task.WhenAll(),並且如果任務拋出異常,這個try catch塊捕捉異常? –

+0

@Tigran是錯誤的。您有幾個選項,最好的(imo)是在單個延續中創建多個代碼路徑。另一個是專門創建一個延續來處理錯誤。 https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskcontinuationoptions%28v=vs.110%29.aspx – Gusdor

+0

@JenishRabadiya:是的。在Wait()方法中,WaitAll()方法會從所有引發異常的任務中接收AggregatedException類型,在它們內部引發異常*未處理*或重新排序*。 – Tigran

1

這些Task實例如果您只是調用構造函數將不會運行。由於任務尚未開始,WhenAll將永遠不會返回,您將死鎖

改爲使用System.Threading.Task.Run

Task t1 = Task.Run(() => { /* Do Something */ }); 
Task t2 = Task.Run(() => { /* Do Something */ }); 
... 

刪除啓動任務的循環。

Task.Run方法(行動)的.NET Framework 4.5

隊列指定的工作對線程池運行和返回任務 處理其工作。

From MSDN

進一步閱讀這裏:Task Parallelism (Task Parallel Library)

關於異常處理,可以使用Task參數來訪問所有的結果,即使例外,在延續中:

Task.WhenAll(allTasks).ContinueWith((t) => 
{ 
    if(t.RanToCompletion) 
    { 
     MyBlockingCollection.CompleteAdding(); 
    } 
    else 
    { 
     Console.WriteLine(t.Exception); 
    } 
}); 

更多關於這裏:Exception Handling (Task Parallel Library)