2009-11-08 14 views
7

Debido a problemas de rendimiento, he reemplazado ReaderWriterLock con ReaderWriterLockSlim. Estoy experimentando problemas causados ​​por un código que funcionaba correctamente cuando usaba un RWL.Reemplazar ReaderWriterLock con ReaderWriterLockSLim - problemas

Como se puede ver, a veces MethodA (que adquiere una escritura bloqueo) llama a otro método (que adquiere una leer bloqueo). El segundo método también se llama desde diferentes lugares, por lo que no siempre hay una colisión de bloqueo. Anteriormente, el bloqueo AcquiringRead no causaba ese problema.

¿Hay alguna solución, excepto la colocación de "si IsRWheld"?

El problema es algo así:

class Avacado 
{ 
    ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); 

    void MethodA() 
    { 
     _lock.TryEnterWriteLock(-1); 
     LockedList.Add(someItem) 
     var result = MethodX(); 
     _lock.ExitWriteLock(); 
    } 

    object MethodX() 
    { 
     //if called from MethodA, it will throw an exception 
     _lock.TryEnterReadLock(-1); 

     //...some stuff with LockedList... 
     var result = LockList.Something(); 

     _lock.ExitReadLock(); 

     return result; 
    } 
} 

Respuesta

8

La llamada a MethodX de MethodA lo califica como el uso recursivo de la cerradura.
véanse las observaciones sobre el MSDN page para ReaderWriterLockSlim:

Por defecto, los nuevos casos de ReaderWriterLockSlim se crean con el LockRecursionPolicy.NoRecursion bandera y no permiten la recursividad. Esta política predeterminada se recomienda para todos los nuevos desarrollos , porque la recursión introduce complicaciones innecesarias y hace que su código sea más propenso a bloqueos. Para simplificar la migración de proyectos existentes que utilizan Monitor o ReaderWriterLock, puede utilizar la bandera LockRecursionPolicy.SupportsRecursion para crear instancias de ReaderWriterLockSlim que permiten recursividad.

4

Otro punto a considerar cuando se sustituye ReaderWriterLock por ReaderWriterLockSlim es que este último implementos IDisposable.

Esto puede hacer que el complejo de reemplazo - como cualquier tipo que posee un ReaderWriterLockSlim también debe ser IDisposable.