我讀過一些關於這裏這個其他職位,但我的問題似乎在(Is the order of static class initialization in C# deterministic?)貼在這裏,一般的智慧和幾個相關的臉飛帖子。靜態初始化VS靜態構造函數,執行命令,釋放模式奇怪的行爲
我有一個ASP.Net 4.0應用程序,和我的Application_Start()方法,通過觸摸的很多東西跑,讓他們成立。其中一件事是爲我們的DAL初始化我們的db連接字符串,其他的初始化其他變量。幾天前,我們的發佈版本開始爆炸了,並且在添加了大量的調試日誌記錄之後,原因竟然是在Application_Start()正式輸入之前調用的新靜態初始化程序並試圖訪問我們的DAL之前已初始化。這似乎與我在其他帖子中看到的有關靜態構造函數和初始化程序執行順序的看法相違背。
具體而言,靜態初始化程序是而不是正在調用它們的代碼中運行;發佈版本中的堆棧跟蹤指示發佈編譯將它們混洗成的一部分,輸入 Application_Startup()。換句話說,堆棧跟蹤在啓動時會在堆棧上顯示Application_Startup() - 但是沒有與其關聯的行號。 DAL初始化的堆棧跟蹤確實顯示行號。
要充實一些僞代碼,我們有
Application_Start()
{
DAL.Inst.GetSetting("ConnectionString"); // tickles the singleton to get the DAL initialized.
// numerous other lines of code
if (!AppUtil.IsAdminAccountSetup)
{ // Do admin account setup
}
// More code
}
public class DAL
{
private static DAL _singleton;
static DAL()
{
_singleton = new DAL();
_singleton.Initialize();
}
public static DAL Inst
{
get { return _singleton; }
}
// all the other methods
}
public class AppUtil
{
private static bool _isAdminSetup = InitializeAdminSetup();
public static bool IsAdminAccountSetup
{
get { return _isAdminSetup; }
}
private static bool InitializeAdminSetup()
{
// Call DAL for query
}
private static bool _isProductRegistered = InitializeProdReg();
public static bool IsProductRegistered
{
get { return _isProductRegistered; }
}
private static bool InitializeProdReg()
{
// Call DAL for query
}
}
AppUtil最近有IsProductRegistered布爾補充說,這似乎是,當事情南下。
Application_Start()中未調用AppUtil.IsProductRegistered,但是當我們查看有關DAL查詢順序的堆棧跟蹤時,我們看到AppUtil.IsProductRegistered的初始化程序調用DAL(在DAL.Inst被觸摸之前)和from Application_Start()(沒有行號)。
然後,我們看到在連接字符串初始化得到的DAL靜態構造函數的一部分,這可以追溯到在的Application_Start(在DAL.Inst參考) - 在這裏它確實顯示的行數。
如果我們改變無論是在AppUtil靜態initialzers到一個單一的靜態構造函數,東西回去參考順序初始化和吹脹消失。
但是,整個情況在我看過的東西里面飛速發展.Net說它會做。
對不起,我希望有足夠的細節來解決這個難題。
爲什麼「靜態initizalizer ...在Application_Start之前調用」令您驚訝?唯一的保證是在第一次使用該類之前調用靜態構造函數。不知道你在帖子中看到的是什麼類型的建議,除了「不要依賴靜態構造函數的任何特定順序/時間調用」。 –
@AlexeiLevenkov靜態構造函數只會在第一次訪問之前立即運行。沒有靜態構造函數的類上的字段初始值設定項可以更早地運行。 – Loki
我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –