【发布时间】:2012-06-20 18:42:54
【问题描述】:
该应用程序是一个 WinForms .net 3.5 应用程序,具有多个项目、一个主项目和多个库项目。如果我从其中一个子项目中存在的单例调用 log4net,它会导致所有日志记录停止。
更新
基于一些 cmets,我通过以下方式更改了 TestSingletonLog4net 类。这些更改仍然存在问题。
- 正如 Jon Skeet 指出的那样,使测试类线程安全。
- 更改了成员声明并添加了 log4net.Config.XmlConfigurator.Configure();按照 Norla 的示例进行配置调用,结果相同,但无论何时调用,所有日志记录都会停止。
这是重现问题的更新类。
public class TestSingletonLog4Net
{
private static volatile TestSingletonLog4Net instance;
private static object syncRoot = new Object();
public static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(TestSingletonLog4Net));
private TestSingletonLog4Net()
{
log4net.Config.XmlConfigurator.Configure();
log.Info("Test write from singleton");
}
public static TestSingletonLog4Net Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new TestSingletonLog4Net();
}
}
return instance;
}
}
}
我设置了一个小项目来复制问题,这就是正在发生的事情。
- 如果我使用主 UI 项目中的 log4net 和单例或普通类日志记录工作。
- 如果我使用子项目库中的 log4net 不是单例日志记录工作。
- 如果我尝试从子项目库之一中的单例中使用 log4net,所有日志记录都会停止,它不仅不会记录,而且从主项目完成的日志记录也不再有效。
我最初将 log4net 配置作为 app.config 的一部分,但我怀疑这可能是一个问题,所以我将 log4net 配置移动到它自己的配置文件中。
使用 log4net 版本 1.2.11
我也尝试过从构造函数外部调用 log,结果相同。
我的设置重置如下。
以下行就在我的 Program.cs 中 using 语句的下方
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
在每个班级我都用以下方式调用 log4net:
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
非常感谢任何有关解决方案的建议。
【问题讨论】:
-
一方面,你的单例实现不是线程安全的......
-
我最初在使用另一个通过 IOC 容器实现为单例的类时发现了这个问题。我刚刚制作了这个测试类来复制问题而没有 IOC 的阻碍。