簡體   English   中英

等待句柄和System.Threading.Tasks命名空間

[英]Wait Handles and the System.Threading.Tasks namespace

當我在System.Threading.Tasks命名空間中使用Parallel.ForEachParallel.For時,是否可以假定所有線程在執行繼續之前已同步?

是否有等同於

WaitHandle.WaitAll(...);

繼續嗎

所以,如果我打電話給

Parallel.ForEach(collection, DoSomethingWithObject);

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

為了擴展Phong的正確答案,Parallel.For和Parallel.ForEach在內部創建了一個所謂的ParallelXXXReplicationTask,它可以同步運行並生成X個子任務,其中X是有效的並發級別(默認為Environment.ProcessorCount)。 每個子任務都與Semphore同步,Semphore會在設置(計數為0)后釋放父任務,以確保僅在所有子任務完成(或崩潰/停止,這由同步設置確定)后,父任務的執行才會返回。 由於parentTask是同步運行的,正在等待中。 您可以確保每當返回對Parallel方法的調用時,所有迭代均已有效完成。

所有任務將在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!");

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

Parallel.ForEach是一個阻止調用。 在每次迭代完成之前,它不會返回。

是否有等效於WaitHandle.WaitAll(...); 繼續嗎

是的,或多或少。 它實際上不會使用WaitHandle.WaitAll因為1)效率極低,並且2)無法擴展,因為它有64個句柄限制。 有幾種非常可擴展的技術可以等待多個任務完成。 我的最愛之一是使用CountdownEvent 1

下面是它的工作原理。 發揮您的想象力並假裝Parallel.ForEach被擴展為以下代碼。 2

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();

1我並不是說這是Parallel.ForEach所使用的技術,但可能與此類似。

2實際上, Parallel.ForEach以更為復雜的方式實現。 我只是想幫助您直觀地了解它如何等待每次迭代完成。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM