2011-06-04 16 views
7

¿Cómo debo estructurar el try/finally cuando uso un SemaphorSlim con token de cancelación para que OperationCancelledException se maneje correctamente? En la Opción A, cancelar la fuente del token arroja OperationCancelledException pero no llama a Release(). En la Opción B, cancelar la fuente del token arroja OperationCancelledException y DOES llama a Release().SemaphoreSlim.Wait (CancellationToken) try/finally adecuado para OperationCancelledException?

// option A: 
_semaphorSlim.Wait(_cancellationTokenSource.Token); 
try 
{ 
    // do work here 
} 
finally 
{ 
    _semaphorSlim.Release(); 
} 


// option B: 
try 
{ 
    _semaphorSlim.Wait(_cancellationTokenSource.Token); 
    // do work here 
} 
finally 
{ 
    _semaphorSlim.Release(); 
} 

Respuesta

6

La opción A es más correcta aquí. No necesita ReleaseSemaphoreSlim cuando cancela, ya que en realidad nunca adquiere e incrementa su conteo. Como tal, no desea liberar a menos que su llamada Wait realmente haya tenido éxito.

De esta MSDN Page on using Semaphore and SemaphoreSlim:

Es responsabilidad del programador para asegurar que un hilo no libera el semáforo demasiadas veces. Por ejemplo, supongamos que un semáforo tiene un recuento máximo de dos, y que el hilo A y el hilo B entran en el semáforo. Si un error de programación en la secuencia B hace que llame a Release dos veces, ambas llamadas tienen éxito. El recuento en el semáforo está lleno, y cuando el hilo A finalmente llama Release, se lanza SemaphoreFullException.

+0

¡muy apreciado! gracias por el enlace también! – SFun28

0

-Lo siento por la respuesta tardía, con suerte podría ayudar a alguien. Como no podemos garantizar el momento de la cancelación y cuando este código puede ser afectado, necesitamos usar la opción A. Luego, en la cláusula final, verifique si se ha utilizado o no el token de cancelación. Si se ha utilizado, entonces no suelte el semáforo.

Cuestiones relacionadas