2009-11-08 2 views
7

Из-за проблем с производительностью я заменил ReaderWriterLock на ReaderWriterLockSlim. Я испытываю проблемы, вызванные кодом, который правильно функционировал, когда он использовал RWL.Замена ReaderWriterLock на ReaderWriterLockSLim - проблемы

Как вы можете видеть, иногда MethodA (который приобретает записи блокировки) вызывает другой метод (который приобретает чтения замка). Второй метод также вызывается из разных мест, поэтому не всегда происходит столкновение блокировок. Ранее блокировка AcquiringRead не вызывала этой проблемы.

Есть ли какое-либо решение, кроме как «если IsRWheld»?

Проблема в том, что-то вроде этого:

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; 
    } 
} 

ответ

8

Вызова MethodX из Methoda квалифицирует это как рекурсивное использование замка.
Смотрите замечания по MSDN page для ReaderWriterLockSlim:

По умолчанию новые экземпляры ReaderWriterLockSlim созданы с LockRecursionPolicy.NoRecursion флага и не позволяют рекурсии. Эта политика рекомендуется для всех новой разработки, потому что рекурсия вводит ненужные осложнения и делает ваш код более склонным к тупикам. Для упрощения миграции из существующих проектов, которые используют Monitor или ReaderWriterLock, вы можете использовать флаг LockRecursionPolicy.SupportsRecursion создавать экземпляры ReaderWriterLockSlim, которые позволяют рекурсию.

4

Еще один момент, который следует учитывать при замене ReaderWriterLock на ReaderWriterLockSlim является то, что последний реализует IDisposable.

Это может сделать заменяющий комплекс, так как любые типы, которые имеют ReaderWriterLockSlim, также должны быть IDisposable.

Смежные вопросы