2013-05-09 57 views
0

我遇到了log4net的一些奇怪的行为,并想知道如果任何人都可以向我解释这一点,我想了解更多,以了解它。奇怪的log4net初始化行为

在我的WPF App.xaml.cs OnStartup覆盖方法,我有以下代码设置用于记录一个log4net的属性:

// logLocation is a path to a subdir in the users' appdata roaming dir 
log4net.GlobalContext.Properties["LogLocation"] = logLocation; 
logger = LogManager.GetLogger(typeof(App)); 
logger.Info("OnStartup: " + string.Join(" ", e.Args)); 

我这样做之前,我创建任何其他记录仪(或所以我想)。

在我的配置文件我有以下行:

<file type="log4net.Util.PatternString" value="%property{LogLocation}" /> 

这个工程可以指定日志文件的位置。但是,我遇到了一个失败的情况 - 导致在执行目录中写入文件名“(null)”。

什么似乎导致这是下面的伪代码,这是在同一OnStartup方法上面的代码之后:

AnyClass ac = new AnyClass(); 
ac.NoOp(); 

其中AnyClass具有实例化的这样的记录器:

private static ILog logger = LogManager.GetLogger(typeof(AnyClass)); 

我使用伪代码的原因是我可以复制这个行为与任何类我实例化和调用的方法。如果没有方法被调用,那么日志路径按预期工作。

几件事情需要注意:

  1. 这时候我在调试或发行模式下的调试器中运行它的工作原理。该错误只出现在我直接运行exe或通过“无需调试开始”。
  2. 如果记录器没有静态定义 - 然后问题消失
  3. 如果我一个静态构造函数添加到AnyClass,然后问题消失,即:

    静态AnyClass(){}

  4. 如果我将调用移到ac.NoOp()到OnStartup调用的辅助方法 - 错误消失。

因此,要回顾一下,误差仅由一个类实例化一个静态记录初始化,并在该类调用OnStartup方法中的方法造成的。

我有几种方法来解决这个问题,但我很想了解更多,以了解为什么会发生这种情况。

+0

你大概可以了解更多通过阅读马克Gravell的答案链接到这个问题的HTTP乔恩斯基特文章://计算器。com/questions/3965976/when-do-static-variables-get-initialized-in-c – sgmoore 2013-05-09 16:55:26

+0

谢谢,请阅读本文。显然静态初始化并不像我想象的那么简单。 – 2013-05-09 17:29:14

回答

0

我认为ac.NoOp();正在创建一个新实例的记录器和新实例不知道什么是PatternString的值。因此正在使用价值null

refer this link

public static Logger getLogger(String name) 

Retrieve a logger named according to the value of the name parameter. 

If the named logger already exists, then the existing instance will be returned. 
Otherwise, **a new instance** is created. 
+1

这应该不重要,因为该属性不是每个记录器。 – sgmoore 2013-05-09 16:45:15

+0

是的。你是对的。 – swapneel 2013-05-09 21:45:03