共享接口和ReaderWriterLockSlim

时间:2009-08-27 20:33:29

标签: .net vb.net multithreading log4net thread-safety

我在一个有多个线程的类中使用log4net,我有一个简单的问题。在log4net.ILog接口上检查属性和调用方法时,是否需要输入readlock / writelock?

我正在使用log4net示例中的建议方法,所以在我所说的类的顶部:

Private Shared ReadOnly log As log4net.ILog = log4net.LogManager.GetLogger(decType) 

由于该类涉及多个与之交互的线程,因此我使用了一个ReaderWriterLockSlim实例来确保我没有使用我的变量进入任何竞争条件。所以回顾一下,如果我想确保我正在练习安全线程,我需要做这样的事情:

If Me.ReaderWriterLockSlim.TryEnterUpgradableReadLock(-1) Then
  If log.IsWarnEnabled Then
    If Me.ReaderWriterLockSlim.TryEnterWriteLock(-1) Then
      log.Warn("Log Message Here")
      Me.ReaderWriterLockSlim.ExitWriteLock()
    End If
  End If
  Me.ReaderWriterLockSlim.ExitUpgradeableReadLock()
End If

或者,我可以简单地这样做:

If log.IsWarnEnabled Then log.Warn("Log Message Here")

P.S。是的,这是粗略的伪代码,我实际上并没有一个名为'ReaderWriterLockSlim'的ReaderWriterLockSlim实例。

2 个答案:

答案 0 :(得分:3)

所以你基本上想知道log4net是否是线程安全的?

来自FAQ

  

是的,log4net是线程安全的。

所以你可以这样做:

If log.IsWarnEnabled Then log.Warn("Log Message Here")

答案 1 :(得分:1)

在上面的示例中,您不需要输入写锁定,因为您没有更改IsWarnEnabled的值。此外,调用TryEnterWriteLock时没有任何意义,无限超时 - 您也可以调用ReaderWriterLockSlim.EnterWriteLock。所以,即使Log4Net不是线程安全的(正如其他人提到的那样),你只需要写:

readerWriterLock.EnterReadLock();
try
{
  if(log.IsWarnEnabled)
    log.Warn("log message here");
}
finally
{
  readerWriterLock.ExitReadLock();
}

然后在更改log.IsWarnEnabled的值时输入写锁定。