2015-10-03 38 views
3

我創建的Task列表,像這樣:Task.WaitAll()如何操作?

public void A() 
{ 

} 

public void B() 
{ 

} 

public void C() 
{ 

} 

public void Ex() 
{ 
    Task.WaitAll(Task.Factory.StartNew(A), Task.Factory.StartNew(B), Task.Factory.StartNew(C)); 
    var p=true; 
} 

現在我的問題是。列表中的所有任務是一個一個地執行還是將它們並行執行。當所有任務都做了,或者它們完成之前

P =真

「P」 設置?

回答

6

對於第一個問題:

將這些任務執行一個由一個或異步。

(在這裏,我想你的意思同時,這是不完全一樣)

使用StartNew將在當前TaskScheduler運行任務。默認情況下表示它將使用ThreadPool,如果線程池中有任何可用插槽,則它將並行運行。如果所有插槽都在任務池中進行,則可能會限制任務的執行,以避免CPU不堪重負,並且可能不會同時執行任務:沒有保證。

這是一個簡單的說明,關於調度策略的更完整和詳細的解釋是explained on the TaskScheduler documentation

作爲一個側面說明。 documentation for StartTask提到StartNew(Action)Run(Action)之間的細微差異。他們不完全等同,不像其他答案中所述。

從.NET Framework 4.5開始,您可以使用Task.Run(Action)方法作爲使用默認參數調用StartNew(Action)的快捷方式。但請注意,兩種方法之間的行爲有所不同:默認情況下,Task.Run(Action)不允許以TaskCreationOptions.AttachedToParent選項啓動的子任務附加到當前Task實例,而StartNew(Action)確實。當所有任務都做了,或者它們完成之前

對於第二個問題

「P」設置?

簡短回答是肯定的。

但是,你應該考慮使用另一種方法,因爲這將阻止你的線程和空閒等待。另一種方法是如果可以,則將控制權交還給調用者,因此線程被釋放並可供CPU使用。如果運行此代碼的線程是ThreadPool的一部分,則尤其如此。

因此,您應該更喜歡using WhenAll()。它返回一個任務,其可以被期待已久的或在其上ContinueWith可以稱爲

例如:

var tasks = new Task[] {Task.Factory.StartNew(A), Task.Factory.StartNew(B), Task.Factory.StartNew(C)}; 
await Task.WhenAll(tasks); 
+0

你可能是指'ThreadPool' – i3arnon

+0

絕對,我的壞。 TaskPool存在,但它是一個Reactive Extension概念。對困惑感到抱歉。 –

2

第一個: 您以錯誤的方式創建任務。當你實例化一個任務時,你需要調用Start方法,否則它什麼都不會。

new Task(() => /* Something * /).Start(); 
如果創建任務,你只是做的方式(通過調用構造函數和擊打開始或使用TaskFacotry甚至Task.Run)默認線程池的線程將專門任務,因此執行任務

在平行下。

Task.WhenAll方法將阻止執行調用方法,直到所有傳遞給它的任務都執行完畢。

因此布爾變量在所有任務完成後設置。

+1

是的,我只是改變了它Task.Factory.StartNew(A)。這個可以嗎 ? –

+2

是的,但是最好的方法是使用Task.Run,​​它對大多數基本場景都更加優化。 – SHM