2012-04-16 9 views
14

Tengo un proyecto Visual Studio 2008 C# .NET 3.5 donde una clase escucha una invocación de evento de otra clase que es multiproceso. Necesito asegurarme de que mi evento solo permita el acceso simultáneo a un máximo de 10 hilos. El undécimo hilo debe bloquearse hasta uno de los 10 finales.Una función que solo permite N hilos concurrentes

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

no tengo control sobre la otra clase MyObj, así que no puedo poner en práctica un conjunto de subprocesos allí.

¿Cuál es la mejor manera de implementar esto?

Gracias, PaulH

Respuesta

21

desea que el Semaphore class. Es, en resumen, un bloqueo que solo permite el acceso de un número determinado de personas que llaman en cualquier momento.

Como no controla la creación de subprocesos, debe tener cuidado con las situaciones de interbloqueo. Los semáforos no son conscientes de la reentrada: si una hebra determinada ingresa a un semáforo más de una vez, tomará más de una ranura. Entonces, si cada uno de los hilos de su interlocutor ingresa a su semáforo más de una vez, existe la posibilidad de un punto muerto.

3

Es costumbre usar un semáforo para esto. Inicialízalo en 10 unidades. wait() para una unidad antes de DoUsefulThings(), signal() una unidad después.

9

Utilice un Semaphore para esto. Los parámetros del constructor son un poco confusos para los que acaban de ser introducidos en la clase. El primer parámetro especifica el número inicial de hilos permitidos a través de en este momento. El segundo parámetro especifica el número máximo de hilos permitidos en un momento dado.

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 para señalar que debe salir del semáforo en el bloque 'finally' de un try/catch. Esto es algo importante: en caso de que su código arroje una excepción, quiere asegurarse de que se cierre el semáforo. –

Cuestiones relacionadas