2012-02-23 77 views
3

當我在System.Threading.Tasks名稱空間中使用Parallel.ForEachParallel.For時,我是否可以假定所有線程都已同步,然後再繼續執行?等待句柄和System.Threading.Tasks命名空間

是否有

WaitHandle.WaitAll(...); 

東西相當於回事?

所以,如果我把類似

Parallel.ForEach(collection, DoSomethingWithObject); 

我可以肯定的是每次調用DoSomethingWithObject完成ForEach回報,或者我需要使用WaitHandles自己?

回答

3

所有任務將在Parallel.ForEach()返回時完成,除非專門調用了Stop()來中止並行執行。在這種情況下,由Parallel.ForEach()返回的ParallelLoopState對象的.IsCompleted屬性將爲false

你可以閱讀一下:

http://msdn.microsoft.com/en-us/library/dd992001.aspx

http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallelloopresult.aspx

你也可以寫一個小的測試應用程序,其中DoSomethingWithObject()是一個很長的運行操作,或Thread.Sleep()通話,以確認這個。執行將阻塞,直到所有線程完成睡眠。

樣品:

Parallel.ForEach(Enumerable.Range(1, 8), 
    i => 
    { 
     Thread.Sleep(5000); 
     Console.WriteLine(i + " done!"); 
    }); 
Console.WriteLine("All done!"); 
+2

謝謝。我寫了一個測試,其中'DoSomethingWithObject'睡了3秒鐘。行爲如預期。 – Anthony 2012-02-23 03:31:00

3

爲了擴大對海防的正確答案,和的Parallel.For內部Parallel.ForEach創建這是同步運行,併產生的子任務X次,其中X爲有效量所謂ParallelXXXReplicationTask的併發級別(默認Environment.ProcessorCount)。每個子任務都與一個一次釋放父任務的Semphore同步(計數爲0),以確保只有在所有子任務完成(或通過同步設置確定的崩潰/停止)後,父任務的執行纔會返回。由於parentTask同步運行並且正在等待。您可以確保每次調用Parallel方法時都會有效完成所有迭代。

2

我可以肯定的是每次調用DoSomethingWithObject已完成 的ForEach返回之前,還是需要使用WaitHandles自己?

Parallel.ForEach是阻止呼叫。直到每次迭代完成後纔會返回。

有沒有相當於WaitHandle.WaitAll(...);

是的,或多或少。它實際上並不使用WaitHandle.WaitAll,因爲1)它的效率非常低,2)由於它具有64個句柄限制,因此它不具有可伸縮性。有幾個非常可擴展的技術可用於等待多個任務的完成。我的最愛之一是使用CountdownEvent

這是它是如何工作的。用你的想象力和假裝Parallel.ForEach得到擴展到下面的代碼。

var finished = new CountdownEvent(1); 
foreach (var item in collection) 
{ 
    var capture = item; 
    finished.AddCount(); 
    Task.Factory.StartNew(
    () => 
    { 
     try 
     { 
     DoSomething(capture); 
     } 
     finally 
     { 
     finished.Signal(); 
     } 
    }); 
} 
finished.Signal(); 
finished.Wait(); 

我不是說這是Parallel.ForEach使用的技術,但它可能是類似的東西。

實際上,Parallel.ForEach以更復雜的方式實現。我只是試圖幫助你想象它如何等待每次迭代完成。

0

Parallel.ForEach()Parallel.For()將阻塞直到其所有任務都已結束,或者是因爲它們已成功完成或因爲它們已被取消。所以是的,在繼續執行之前,所有線程都被同步。