2012-04-16 75 views
14

我有一個Visual Studio 2008 C#.NET 3.5項目,其中一個類監聽來自另一個多線程類的事件調用。我需要確保我的事件只允許同時訪問最多10個線程。第11個線程應該阻塞,直到10個完成之一。一個函數,只允許N個併發線程

myobj.SomeEvent += OnSomeEvent; 

private void OnSomeEvent(object sender, MyEventArgs args) 
{ 
    // allow up to 10 threads simultaneous access. Block the 11th thread. 
    using (SomeThreadLock lock = new SomeThreadLock(10)) 
    {   
     DoUsefulThings(args.foo); 
    } 
} 

我沒有在其他MyObj類的控制,所以我不能實現一個線程池那裏。

實現此目的的最佳方法是什麼?

感謝, PaulH

回答

21

你想要Semaphore class。簡而言之,它是一個只允許指定數量的呼叫者在任何時間通過的鎖。

由於您不控制線程的創建,因此您需要小心有關死鎖的情況。信號量不會重入意識 - 如果給定的線程不止一次地進入信號量,它將佔用多個時隙。所以如果你的每個調用者的線程不止一次地進入你的信號量,就有可能發生死鎖。

3

爲此,習慣使用信號量。初始化爲10個單位。在DoUsefulThings()之前等待()一個單位,然後在一個單位之後信號()。

9

爲此,請使用Semaphore。這些構造函數參數對於剛剛介紹給這個類的人來說有點混亂。第一個參數指定現在通過允許的初始線程數。第二個參數指定在任何給定時間允許通過的最大線程數。

myobj.SomeEvent += OnSomeEvent; 
Semaphore semaphore = new Semaphore(10, 10); 

private void OnSomeEvent(object sender, MyEventArgs args) 
{ 
    semaphore.WaitOne(); 
    try 
    { 
    DoUsefulThings(args.foo); 
    } 
    finally 
    { 
    semaphore.Release(); 
    } 
} 
+1

+1注意你應該在try/catch的'finally'塊中退出信號量。這是重要的東西 - 萬一你的代碼拋出一個異常,你想確保信號退出。 – 2012-04-16 15:36:04

相關問題