ReaderWriterLockSlim是正确的选择吗?

时间:2011-03-04 00:51:51

标签: c# .net multithreading readerwriterlockslim

我正在为在Windows Azure中运行的应用程序编写全局错误处理程序/记录程序。当应用程序中发生错误时,将执行需要以原子方式执行的许多操作。我需要防止在上一个错误完成之前记录错误。同时,我希望根据需要读取日志。

我最初的想法是使用Monitor / lock并仅锁定错误写入。这样就完全没有抑制读取。我想知道ReaderWriterLockSlim是否更合适。我不能说我真正理解一种方法与另一种方法之间的价值。

我应该创建一个ReaderWriterLockSlim并执行以下操作(将读取包装在EnterReadLock中)...

public static void LogError(Exception exception)
{
    _lock.EnterWriteLock();

    ...

    _lock.ExitWriteLock();
}

或者我只是执行以下操作,只锁定写入部分:

public static void LogError(Exception exception)
{
     lock (someStaticLock)
     {
        ...
     }
}

非常感谢任何想法/建议。

3 个答案:

答案 0 :(得分:4)

好的,这完全取决于预期的资源争用情况。以下是我根据锁定内容和锁定量做出的简单决定。

ReaderWriterLockSlim是使用自旋锁实现的,因此如果你有很长的锁定资源(在这种情况下写文本),由于等待线程的旋转会导致性能下降。也就是说,它是以下情况下非常有用的工具。

  • 如果你有很多锁,并且每一个都是更精细的(对于非常小的代码片段的锁),那么ReaderWriterLockSlim或(spinlock)。
  • 预期的线程或争用的数量是高螺旋锁是有意义的,只要锁定是细粒度的。

锁定或监视器最适合您的争用是粗粒度并且您知道争用或锁定数量较少。

ReaderWriterLockSlim比ReaderWriterLock快了至少3-5次。

答案 1 :(得分:4)

为什么不使用队列来存储异常,并在后台工作线程中将它们吐出来?然后你可以锁定每一侧的入队/出队。碰撞窗口可以保持相当小,如果你的日志数据的实际写入落后,也可以,因为订单会被保留。如果需要,可以将Exception包装在某个集合中,该集合包含项目入队时的时间戳,以便您可以对它们进行适当的时间戳记。

答案 2 :(得分:-1)

好吧,我认为你不应该在没有锁定的情况下阅读,因为你可以在原子操作过程中阅读。 ReaderWriterLock似乎更好,因为它保证在写入过程中没有读者可以进入。