2011-08-15 14 views
14

El código siguiente es de MSDN:C# - Bloqueo pregunta usando EnterWriteLock

private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(); 
private Dictionary<int, string> innerCache = new Dictionary<int, string>(); 

public void Add(int key, string value) 
{ 
    cacheLock.EnterWriteLock(); 
    try 
    { 
     innerCache.Add(key, value); 
    } 
    finally 
    { 
     cacheLock.ExitWriteLock(); 
    } 
} 

que he visto código como este en otra places.The EnterWriteLock() es siempre fuera del bloque try. ¿Alguien sabe por qué no está dentro del bloque de prueba?

Respuesta

17

Supongamos que el EnterWriteLock() falla. Por cualquier razón.

Entonces lo único que no debes hacer es salir de un bloqueo que nunca entraste.

Es un patrón muy básico que también se aplica, por ejemplo, a las transmisiones, pero que no se ve con tanta frecuencia gracias a la declaración using() {}.

var s = File.Create(...); 
// (only) if the previous line succeeded, 
// we gain the responsibility to close s, no matter what 
try 
{ 
    // do some I/O 
} 
finally 
{ 
    s.Dispose(); 
} 
5

Porque eso sería un error. No puede llamar a ExitWriteLock hasta que esté seguro de haberlo ingresado. Imagínese lo que sucede si lo mueve adentro try {} y EnterWriteLock() arroja una excepción. Esa es una doble kaboom. Kabloom, arruina el mensaje de excepción.

3

Si EnterWriteLock arroja una excepción, no hay necesidad de llamar a ExitWriteLock, de ahí la razón por la que no está en el bloque try. ExitWriteLock siempre debe invocarse si se invoca satisfactoriamente EnterWriteLock. Es posible que desee envolver un bloque try alrededor de EnterWriteLock en ciertos escenarios, ya que puede lanzar una LockRecursionException. ExitWriteLock también puede arrojar una SynchronizationLockException y puede requerir un bloque de prueba en su aplicación.