2012-04-16 11 views
14

Mam projekt Visual Studio 2008 C# .NET 3.5, gdzie klasa nasłuchuje wywołania zdarzenia z innej klasy, która jest wielowątkowa. Muszę się upewnić, że moje wydarzenie pozwala tylko na jednoczesny dostęp do maksymalnie 10 wątków. 11. wątek powinien zablokować się, aż jeden z 10 zakończy się.Funkcja zezwalająca tylko na N równoczesnych wątków

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

nie mam kontroli nad drugim MyObj klasy, więc nie mogę realizować tam puli wątków.

Jaki jest najlepszy sposób wdrożenia tego?

Dzięki PaulH

Odpowiedz

21

Chcesz Semaphore class. Krótko mówiąc, jest to blokada, która zezwala tylko na określoną liczbę osób dzwoniących w dowolnym momencie.

Ponieważ nie kontrolujesz tworzenia wątków, musisz uważać na sytuacje zakleszczenia. Semafory nie są przytomne - jeśli dany wątek wchodzi do semafora więcej niż jeden raz, zajmie więcej niż jedno gniazdo. Jeśli więc każdy wątek twojego rozmówcy wchodzi do twojego semafora więcej niż raz, istnieje możliwość zakleszczenia.

3

Zwykle używa się do tego semafora. Zainicjuj go na 10 jednostek. wait() dla jednej jednostki przed DoUsefulThings(), signal() następnie jedną jednostkę.

9

Użyj do tego celu Semaphore. Parametry konstruktora są trochę mylące dla tych, którzy dopiero zapoznają się z klasą. Pierwszy parametr określa początkową liczbę wątków dozwoloną przez w tej chwili. Drugi parametr określa maksymalną liczbę wątków dozwolonych w danym momencie.

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 dla stwierdzenia, że ​​należy wyjść z semafora w bloku 'finally' w try/catch. To ważne rzeczy - na wypadek, gdyby kod wygenerował wyjątek, chcesz się upewnić, że semafor został zakończony. –

Powiązane problemy