2009-11-04 3 views
2

Здравствуйте, мне нужно использовать writereaderlock в моем методе. Я хочу знать, как это правильно использовать.Как правильно использовать readerwriterlock

Я получил словарь Objecta

public class ObjectA 
{ 
    public ReaderWriterLock RWL {get;set;} 
    public ObjectB obj {get;set;} 
    public ObjectA() 
    { 
     RWL = new ReaderWriterLock(); 
    } 
} 

public class ObjectB 
{ 
    int TTL {get;set;} 
    string Value {get;set;} 
} 

В моем методе я использую словарь Objecta, ключ является Guid, поэтому предполагают, что, когда я называю Dict [справ] всегда возвращает экземпляр моего Objecta (для Exemple)

public foo() 
{ 
    ObjecA objA = dict[guid]; 
    objA.RWL.AcquireReaderLock(500); 
    if(objA.obj.TTL<=0) 
    { 
     objA.obj.RWL.AcquireWriterLock(1000); 
     objA.obj.Value = DateTime.Now().ToString(); 
     objA.obj.RWL.ReleaseWriterLock(); 
    }else{ 
     int ttl = objA.obj.TTL; 
     Interlocked.Decrement(ref ttl); 
    }  
    objA.RWL.ReleaseReaderLock(); 
} 

Я действительно не уверен, что я с помощью читателя и писателя там, как же мне нужно использовать для чтения замок писатель, с условной проверки?

+0

Возможно, вы точно не уменьшаете TTL. Вы атомизировали декремент переменной стека, а не член класса. –

ответ

6

Есть много проблем с этим кодом, в том числе:

  • вы на самом деле не всегда декремент TTL в классе instance--, как Николай указывает, вы декремента локальную переменную! Interlocked.Decrement(ref objA.obj.TTL) - как это сделать правильно.
  • вы не устанавливаете начальное значение TTL, поэтому оно всегда будет равным нулю (если не используется какой-либо другой код, который, вероятно, не имеет отношения к классу, чувствительному к потокам, где обычно требуется весь код, связанный с потоком в том же классе, чтобы не потерять контроль над тем, кто что делает)
  • вы должны использовать ReaderWriterLockSlim, который теперь предпочитают более старый класс ReaderWriterLock. См. Последнюю гиперссылку для почему.
  • При приобретении блокировки записи, если у вас уже есть блокировка чтения, вам необходимо обновить блокировку - для этого обычно существует отдельный метод для класса блокировки. Аналогично, после обновления, для освобождения блокировки требуется один способ освобождения блокировки, а не один, чтобы освободить блокировку записи, а другой - освободить предыдущую блокировку чтения.
  • вам придется иметь дело с случаем сбоя, когда вы не можете приобрести блокировки.
  • вы захотите обернуть код в using или try/finally блоками, чтобы гарантировать освобождение ресурсов, даже если возникает исключение.

Возможно, стоит подумать над тем, действительно ли вам нужно использовать блокировки чтения/записи, вместо того, чтобы использовать что-то более простое, например, lock{} statement. Правильно блокировать блокировки чтения/записи и избегать взаимоблокировок сложно даже для разработчиков, которые хорошо знают эти API и концепции, и даже тогда они обычно резервируют их использование только для самых критически важных мест (1000 + в секунду). Другими словами, вам может быть лучше начать с более простого подхода, используя lock{}, и только возвращаться к использованию ReaderWriterLockSlim, если производительность неприемлема.

В качестве отправной точки, я предлагаю вам добавить еще некоторую информацию на Ваш вопрос:

  • первый, включать высокоуровневое описание того, что вы пытаетесь сделать, в том числе требования высокого уровня для функциональности и производительности. это может помочь нам порекомендовать правильное решение и знать, является ли блокировка чтения/записи правильной.
  • попытайтесь записать в псевдокоде или просто английском, точно, как вы хотите, чтобы ваш код работал, в том числе, как вы хотите решить логические проблемы выше (например, что делать, когда происходит тайм-аут, как устанавливается TTL , и т.д.)
  • пересмотреть свой образец кода, чтобы включить исправления некоторые/все проблемы, которые я отметил выше

я гарантирую вам, что если вы включите эту addiitonal данные в вашем вопросе, вы получите лучшие ответы, которые могут помочь вы с любыми остальными проблемами с кодом. :-)

+0

Спасибо за ваш ответ, но код, который я показывал, был всего лишь примером, я использовал свой код в HttpHandler, блокировка действительно замедляется для моего веб-приложения. Я попробую с ReaderWriterLockSlim Спасибо. Я нахожу, что могу укрепить свой читательский замок до писателя, и эта информация поможет мне. Спасибо –

+0

Отличный ответ - очень полезно! – torial

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