ReaderWriterLock se utiliza para sincronizar el acceso a un recurso. En cualquier momento dado, permite el acceso de lectura simultáneo de varios subprocesos o el acceso de escritura de un solo subproceso. En una situación en la que un recurso se cambia raramente, ReaderWriterLock proporciona mejor rendimiento que un simple bloqueo de uno en uno, como Monitor.
ReaderWriterLock funciona mejor si la mayoría de los accesos son de lectura y las escrituras son pocas y de corta duración. Se alternan varios lectores con escritores únicos, para que ni lectores ni escritores queden bloqueados largos períodos de tiempo.
Nota: |
|---|
| Si se mantienen bloqueos de lectores o de escritores durante largos períodos de tiempo, otros subprocesos quedarán sin recursos. Para obtener un mejor rendimiento, se puede reestructurar la aplicación de manera que se minimice la duración de las escrituras. |
Un subproceso puede contener un bloqueo de lector o de escritor, pero no los dos a la vez. En lugar de liberar un bloqueo de lector para adquirir el bloqueo de escritor, se puede utilizar UpgradeToWriterLock y DowngradeFromWriterLock.
Las solicitudes de bloqueo recursivas aumentan el recuento de bloqueos de un bloqueo.
Los lectores y los escritores forman colas independientes. Cuando un subproceso libera el bloqueo del escritor, todos los subprocesos en espera de la cola del lector reciben en ese momento bloqueos de lector; cuando se liberan todos esos bloqueos de lector, el siguiente subproceso en espera de la cola del escritor, si lo hay, recibe un bloqueo de escritor, y así sucesivamente. En otras palabras, ReaderWriterLock alterna entre una colección de lectores y un escritor.
Si hay un subproceso en la cola del escritor esperando a que se liberen bloqueos activos de lector, los subprocesos que solicitan nuevos bloqueos de lector se acumulan en la cola del lector. Estas solicitudes no se conceden, aunque podrían compartir el acceso simultáneo con propietarios de bloqueos de lector existentes; de esta forma se ayuda a proteger a los escritores frente a bloqueos indefinidos por parte de los lectores.
La mayoría de los métodos para adquirir bloqueos en un ReaderWriterLock aceptan valores de tiempo de espera. Utilice tiempos de espera para evitar interbloqueos en la aplicación. Por ejemplo, un subproceso puede adquirir el bloqueo de escritor en un recurso y, a continuación, solicitar un bloqueo de lector en otro; mientras tanto, otro subproceso podría adquirir el bloqueo de escritor del segundo recurso y solicitar un bloqueo de lector en el primero. A menos que se utilicen tiempos de espera, los subprocesos se interbloquean.
Si se agota el tiempo de espera y la solicitud de bloqueo no se ha concedido, el método devuelve el control al subproceso que realiza la llamada produciendo ApplicationException. Un subproceso puede detectar esta excepción y decidir qué se debe hacer a continuación.
Los tiempos de espera se expresan en milisegundos. Si se utiliza System.TimeSpan para especificar el tiempo de espera, el valor utilizado es el número total de milisegundos que representa TimeSpan. En la tabla siguiente se muestran los valores de tiempo de espera válidos, en milisegundos.
| Valor | Descripción |
| -1 | Infinite. |
| 0 | Sin tiempo de espera. |
| > 0 | Número de milisegundos durante los que se va a esperar. |
A excepción de -1, no se admiten valores de tiempo de espera negativos. Si se utiliza un entero negativo que no sea -1 para especificar el tiempo de espera, se utiliza cero (sin tiempo de espera). Si se especifica un TimeSpan que representa un número negativo de milisegundos que no sea -1, se produce ArgumentOutOfRangeException.