我在一个有多个线程的类中使用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
实例。
答案 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的值时输入写锁定。