2010-08-11 77 views
1

我有30多個可以並行執行的任務。
我爲每個任務使用ThreadPool。
但是,在所有任務完成之前,父函數不應該返回。從線程池加入線程

我需要一個線程同步處理時,其計數到達0 類似的東西會釋放的WaitOne:

foo.StartWith(myTasks.Count); 
foreach (var task in myTasks) { 
    ThreadPool.QueueUserWorkItem(state => { task(state); foo.Release(); }); 
} 
foo.WaitOne(); 

Semaphore感覺不錯,只是無法弄清楚如何在這裏使用它。

+0

不把它作爲答案,因爲它與你的問題相切,但如果你使用BeginInvoke而不是作爲線程池項目開始這些任務,你可以從AysncResults中獲得WaitHandles,並且在它們上調用WaitAll。如果線程池的優點超過了這個,那麼這不是一個很好的答案,但是如果沒有,那麼值得一看。 – 2010-08-11 01:10:28

回答

9
int running = myTasks.Count; 
AutoResetEvent done = new AutoResetEvent(false); 
foreach (var task in myTasks) { 
    ThreadPool.QueueUserWorkItem(state => { 
    task(state); 
    if (0 == Interlocked.Decrement(ref running)) 
     done.Set(); 
    }); 
} 
done.WaitOne(); 

使用C#4.0,您可以使用新的CountdownEvent原語。

+2

或4.0任務類,更好的捕鼠器。 – 2010-08-11 00:48:32

0

根據這篇文章:Overview of Synchronization Primitives

C#有一個內置的類型,這種情況下,CountDownEvent:CountdownEvent Class

或者一個類似的一個:Barrier (.NET Framework)

對於較新的版本,使用TPL(任務並行庫),並且對於這個scenerio這個代碼是相關的:

// Create an ActionBlock<int> object that prints its input 
// and throws ArgumentOutOfRangeException if the input 
// is less than zero. 
var throwIfNegative = new ActionBlock<int>(n => 
{ 
    Console.WriteLine("n = {0}", n); 
    if (n < 0) 
    { 
     throw new ArgumentOutOfRangeException(); 
    } 
}); 

// Post values to the block. 
throwIfNegative.Post(0); 
throwIfNegative.Post(-1); 
throwIfNegative.Post(1); 
throwIfNegative.Post(-2); 
throwIfNegative.Complete(); 

// Wait for completion in a try/catch block. 
try 
{ 
    throwIfNegative.Completion.Wait(); 
} 
catch (AggregateException ae) 
{ 
    // If an unhandled exception occurs during dataflow processing, all 
    // exceptions are propagated through an AggregateException object. 
    ae.Handle(e => 
    { 
     Console.WriteLine("Encountered {0}: {1}", 
     e.GetType().Name, e.Message); 
     return true; 
    }); 
} 

/* Output: 
n = 0 
n = -1 
Encountered ArgumentOutOfRangeException: Specified argument was out of the range 
of valid values. 
*/ 

https://msdn.microsoft.com/en-us/library/hh228603.aspx