2010-03-22 14 views
6

Se han escrito muchas cosas sobre la clase ReaderWriterLockSlim que permite lectura múltiple y una sola escritura. Todos estos (al menos que he encontrado) dicen cómo usarlo sin mucha explicación sobre por qué y cómo funciona. El ejemplo de código estándar es:.NET ReaderWriterLockSlim issues

lock.EnterUpgradeableReadLock(); 

try 
{ 
    if (test if write is required) 
    { 
     lock.EnterWriteLock(); 

     try 
     { 
      change the resourse here. 
     } 
     finally 
     { 
     lock.ExitWriteLock(); 
     } 
    } 
} 
finally 
{ 
    lock.ExitUpgradeableReadLock(); 
} 

La pregunta es: si lo permite el bloqueo actualizable un solo hilo para entrar en su sección, por la que debe llamar al método EnterWriteLock dentro? ¿Qué pasará si no lo hago? ¿O qué sucederá si en lugar de EnterUpgradeableReadLock voy a llamar a EnterWriteLock y escribiré en un recurso sin utilizar ningún bloqueo actualizable?

Respuesta

9

La ventaja de utilizar EnterUpgradeableReadLock sobre EnterReadLock es que se puede estar seguro de que la condición que compruebe con el fin de determinar si se debe entrar en el bloqueo de escritura o no no cambia entre la comprobación de la condición y, de hecho entrar en el escribir bloqueo Esto evita la duplicación que puede ser necesaria con regulares lock s:

if (whatever-condition) 
{ 
    lock (_lockObject) 
    { 
     // the condition may have changed betwen the check and the lock; verify 
     // that the condition is still valid 
     if (whatever-condition) 
     { 
      // do the stuff 
     } 
    } 
} 

Al mismo tiempo, se hace no llamadas de bloque a EnterReadLock, por lo demás hilos pueden todavía conseguir acceso de lectura en otras partes del código (y esas llamadas, por supuesto, bloquearán la llamada al EnterWriteLock hasta que liberen los bloqueos de lectura).

+0

¡Gracias a todos! Como puedo aceptar una respuesta única, elegí (subjetivamente) esta como la más informativa. – Kamarey

1

La clase ReaderWriterLockSlim esencialmente envuelve el bloqueo de escritura y permite que todos los lectores lo lean siempre que no se mantenga el bloqueo de escritura. Una vez que se mantiene el bloqueo de escritura, ningún lector puede leer.

La idea detrás de EnterUpgradeableReadLock es simplemente permitir que el programador indique explícitamente su intención y no modifique nada accidentalmente.

pm100 - es más rápido porque un bloqueo no es exclusivo, ya que muchos hilos pueden leer a la vez lo que puede acelerar la lectura de aplicaciones pesadas. De hecho, si su aplicación es pesada, esta podría no ser la mejor solución de bloqueo para usted. Esto funciona mejor cuando las modificaciones rara vez se hacen, pero se requieren muchas lecturas.

+0

Usted dice que EnterUpgradeableReadLock es solo para explicitud y teóricamente puede ser reemplazado por EnterWriteLock? – Kamarey

+0

Internamente. Si solo usa EnterWriteLock, bloqueará a los lectores, por lo que no es bueno hacerlo. – Chris

3

si lo permite el bloqueo actualizable sólo solo hilo para entrar en su sección, por qué debería llamar EnterWriteLock método dentro?

EnterWriteLock bloquearía otros subprocesos que solo necesitan leerse: si utiliza un bloqueo actualizable, otros subprocesos aún pueden obtener bloqueos de lectura. Desde el EnterUpgradableLock documentación:

Sólo un hilo puede entrar en el modo actualizable en un momento dado. Si un hilo es en modo actualizable, y no hay hilos esperando para entrar en el modo de escritura, cualquier número de otros hilos puede entrar modo de lectura, incluso si hay hilos esperando para entrar en el modo actualizable.

+0

No EnterUpgradeableReadLock también bloquea todos los hilos hasta que se cierra? – Kamarey

+0

No, actualizaré mi respuesta con la parte relevante de la documentación. –