2011-02-01 235 views
2

我遇到了一個問題,其中一個類的靜態構造函數在它應該被調用之前被調用。 (即,DI/IoC沒有設置,它從服務定位器返回空/異常)。跟蹤靜態構造函數執行

我不幸沒有很多對靜態構造函數的控制,不要問我爲什麼要依靠DI/IoC來建立,但它是。

在我的應用程序中,沒有任何應該引用此類靜態或否則在我的IoC準備就緒之前,但靜態構造函數仍在執行。

有沒有簡單的方法來確定哪些行導致構造函數執行? 注:我不能在static constructor斷點,因爲這一切發生之前,ASP.NET遠程調試器可以連接到(在Global.asax.cs中)

回答

1

您無法控制何時執行靜態構造函數。 將你正在做的從你的構造函數移動到一個靜態的Initialize()函數。 只要你準備好就打電話給那個。 不要依賴於何時執行靜態構造函數。

入住這link

靜態構造函數有以下

性質:

靜態構造函數被調用 一審之前自動初始化類 創建 或任何靜態成員都被引用。

靜態構造函數不能直接調用 。

用戶無法控制何時在 程序中執行了靜態構造函數 。

+0

是啊,我想盡可能多。不幸的是,我正在處理我沒有寫在這裏的代碼> _> – Aren 2011-02-01 19:54:49

12

Web服務器和往常一樣,使用:

Debugger.Break() 
+1

很想,如果我能修改構造函數...... – Aren 2011-02-01 19:56:17

+0

@Aren:你總是可以只寫代碼在`global.asax`文件,P – leppie 2011-02-01 19:58:51

2

這可以使用Windbg和sosex來完成。下面是示例代碼

using System; 
namespace Code 
{ 
class Test 
{ 
    public static int i; 
    static Test() 
    { 
    i = 10; 
    Console.WriteLine(i); 
    } 
    static void Main() 
    { 
    Console.WriteLine(Test.i); 
    Console.Read(); 
    } 
} 
} 

而且這裏的步驟

  1. 安裝過程中WinDbg的使用.load sosex
  2. 下一頁發出命令!mbm *Code.Test..cctor*
  3. 的中斷調試上
  4. 負載sosex致電 靜態構造函數,之後您可以發出!mk以獲得 調用堆棧

下面是!mk輸出爲上述樣品

0:000> !mk 
Thread 0: 
    ESP    EIP 
00:M 000000000026def8 000007ff00150120 Code.Test..cctor()(+0x0 IL)(+0x0 Native) 
01:U 000000000026df00 000007fef43a10b4 clr!CallDescrWorker+0x84 
02:U 000000000026df40 000007fef43a11c9 clr!CallDescrWorkerWithHandler+0xa9 
03:U 000000000026dfc0 000007fef43a32b4 clr!DispatchCallDebuggerWrapper+0x74 
04:U 000000000026e060 000007fef43aafdf clr!MethodTable::RunClassInitEx+0x1ff 
05:U 000000000026e1b0 000007fef43aaca8 clr!MethodTable::DoRunClassInitThrowing+0x55e 
06:U 000000000026ec70 000007fef43a3470 clr!MethodTable::CheckRunClassInitThrowing+0xe3 
07:U 000000000026eca0 000007fef44cb848 clr!MethodDesc::DoPrestub+0x587 
08:U 000000000026edb0 000007fef43a23f3 clr!PreStubWorker+0x1df 
09:U 000000000026ee70 000007fef4362d07 clr!ThePreStubAMD64+0x87 
0a:U 000000000026ef40 000007fef43a10b4 clr!CallDescrWorker+0x84 
0b:U 000000000026ef80 000007fef43a11c9 clr!CallDescrWorkerWithHandler+0xa9 
0c:U 000000000026f000 000007fef43a1245 clr!MethodDesc::CallDescr+0x2a1 
0d:U 000000000026f230 000007fef44a1675 clr!ClassLoader::RunMain+0x228 
0e:U 000000000026f480 000007fef44a17ac clr!Assembly::ExecuteMainMethod+0xac 
0f:U 000000000026f730 000007fef44a1562 clr!SystemDomain::ExecuteMainMethod+0x452 
10:U 000000000026fce0 000007fef44a3dd6 clr!ExecuteEXE+0x43 
11:U 000000000026fd40 000007fef44a3cf3 clr!CorExeMainInternal+0xc4 
12:U 000000000026fdb0 000007fef4527365 clr!CorExeMain+0x15 
13:U 000000000026fdf0 000007fef6883309 mscoreei!CorExeMain+0x41 
14:U 000000000026fe20 000007fef6915b21 MSCOREE!CorExeMain_Exported+0x57 
15:U 000000000026fe50 0000000077a6f56d KERNEL32!BaseThreadInitThunk+0xd 
16:U 000000000026fe80 0000000077ba3021 ntdll!RtlUserThreadStart+0x1d 

HTH

0

也許你應該跳過使用靜態構造函數?是否一定?

public class SomeClass 
{ 
    private static bool IsInizialized = false; 

    public SomeClass() 
    { 
     if (!IsInizialized) 
     { 
      // static constuctor thread safe but this doesn't 
      // 
      lock (this) 
      { 
       if (!IsInizialized) 
       { 
        IsInizialized = true; 
        // all what static constructor does 
       } 
      } 
     } 
    } 
}