C#条件锁

时间:2016-06-10 07:14:25

标签: c# multithreading performance locking

我正在编写性能关键代码,因此希望尽量减少对lock(){ ... }的调用 关键部分是字典:

private static readonly Dictionary<string, System.Messaging.MessageQueue> _messageQueues;

当同时读取和添加到该词典时,可能会有损坏的数据。这就是为什么我不想同时允许这两个操作。

解决方案1 ​​

lock (_lock) {
   _messageQueues.Add(queueName, result);
}

并在另一种方法中:

lock(_lock){
   if (_messageQueues.TryGetValue(queueName, out result)) {
      return result;
   }
}

但我不喜欢这个解决方案,因为现在只有一个线程可以一次读取。
如果目前正在进行写作,我想允许多个读者或不读。

解决方案2
添加布尔字段:

private static volatile bool _currentlyModifying;

像这样写字典:

try {
   _currentlyModifying = true;
   lock (_lock) {
      _messageQueues.Add(queueName, result);
   }
}
finally {
   _currentlyModifying = false;
}

并且这样读:

if (_currentlyModifying) {
   lock (_lock) {
      if (_messageQueues.TryGetValue(queueName, out result)) {
         return result;
      }
   }
} else {
   //Here is the new problem
   if (_messageQueues.TryGetValue(queueName, out result)) {
      return result;
   }
}

问题
这样可以很好地运作,但是存在竞争条件:
一个线程可以在另一个线程开始读取后立即开始写入 有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

如评论中所述,您可以使用ConcurrentDictionary。如果您没有这个,那么您可以将代码分段给读者和作者(如小规模的CQRS :)并使用ReaderWriterLockSlim类来优化性能。