2013-05-09 62 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