2011-02-01 166 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 
       } 
      } 
     } 
    } 
}