2012-04-16 12 views
14

Ho un progetto Visual Studio 2008 C# .NET 3.5 in cui una classe ascolta una chiamata di evento da un'altra classe che è multithread. Devo assicurarmi che il mio evento consenta l'accesso simultaneo a un massimo di 10 thread. L'11 ° thread dovrebbe bloccare fino a quando uno dei 10 finisce.Una funzione che consente solo N thread simultanei

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

Non ho il controllo sopra l'altra MyObj di classe, quindi non posso implementare un ThreadPool lì.

Qual è il modo migliore per implementarlo?

Grazie, Paulh

risposta

21

Volete il Semaphore class. È, in breve, un blocco che consente di accedere a un determinato numero di chiamanti in qualsiasi momento.

Poiché non si controlla la creazione di thread, è necessario prestare attenzione alle situazioni di deadlock. I semafori non sono consapevoli della rientranza: se un dato thread entra in un semaforo più di una volta, ci vorrà più di uno slot. Quindi, se ogni thread del chiamante entra nel tuo semaforo più di una volta, c'è la possibilità di un deadlock.

3

È consuetudine utilizzare un semaforo per questo. Inizializza a 10 unità. aspetta() per una unità prima di DoUsefulThings(), signal() un'unità dopo.

9

Utilizzare uno Semaphore per questo. I parametri del costruttore sono un po 'di confusione per quelli appena introdotti nella classe. Il primo parametro specifica il numero iniziale di thread consentiti tramite al momento. Il secondo parametro specifica il numero massimo di thread consentiti in un dato momento.

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 per notare che è necessario uscire dal semaforo nel blocco 'finally' di un try/catch. Questa è una cosa importante - nel caso in cui il tuo codice generi un'eccezione, vuoi assicurarti che il semaforo sia chiuso. –

Problemi correlati