3

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

我最初的想法是使用监视器/锁定并仅锁定错误写入。这样,读取根本不会受到抑制。我想知道 ReaderWriterLockSlim 是否更合适。我不能说我真正理解一种方法与另一种方法之间的价值。

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

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

    ...

    _lock.ExitWriteLock();
}

还是我只是简单地执行以下操作,仅锁定写入部分:

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

任何想法/建议将不胜感激。

4

3 回答 3

4

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

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

  • 如果您有很多锁,并且每个锁的粒度都更细(锁定非常小的代码段),那么 ReaderWriterLockSlim 或(自旋锁)。
  • 如果锁定是细粒度的,则预期的线程数或争用数很高 spinlock 是有意义的。

当您的争用是粗粒度的并且您知道争用或锁的数量较少时,Lock 或 Monitor 最适合。

ReaderWriterLockSlim 比 ReaderWriterLock 至少快 3-5 倍。

于 2011-03-04T01:17:30.107 回答
4

为什么不使用队列在异常发生时存储它们并将它们吐出到后台工作线程中?然后你可以锁定每一侧的入队/出队。冲突的窗口可以保持相当小,如果您实际写入日志数据的时间晚了也没关系,因为顺序被保留了。如果需要,您可以将 Exception 包装在某个集合中,该集合包括项目入队时间的时间戳,以便您可以适当地为它们加上时间戳。

于 2011-03-04T02:33:36.983 回答
0

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

于 2011-03-04T01:04:40.567 回答