2011-02-01 3 views
2

Я столкнулся с проблемой здесь, когда статический конструктор одного из моих классов вызывается до того, как он будет. (I.e, DI/IoC не настроен, и он возвращает null/исключения из локатора службы).Отслеживание выполнения статического конструктора

У меня, к сожалению, нет большого контроля над статическим конструктором, не спрашивайте меня, почему он полагается на DI/IoC для настройки, но это так.

В моем приложении ничто не должно ссылаться на этот класс static или иначе, прежде чем мой IoC готов к работе, но статический конструктор все равно выполняется.

Есть ли простой способ определить, какая строка запустила конструктор? Примечание: Я не могу останова в static constructor, потому что все это происходит до того, как удаленный отладчик для ASP.NET может подключаться к веб-серверу (в Global.asax.cs)

ответ

1

У вас нет контроля над тем, когда выполняется статический конструктор. Переместите все, что вы делаете, от вашего конструктора до статического Инициализировать(). Назовите это, когда будете готовы. Не зависеть от того, когда выполняется статический конструктор.

Проверить это link

Статические конструкторы имеют следующие

свойства:

Статический конструктор вызывается автоматически инициализировать класс перед первой инстанции создается или любые статические члены ссылаются.

Статический конструктор нельзя называть .

Пользователь не имеет контроля над тем, когда статический конструктор выполнен в программе .

+0

Да, я понял, как много. К сожалению, я имею дело с кодом, который я здесь не написал> _> – Aren

+0

Да, в конечном итоге вы подтвердили, что я подозревал. То есть этот подход действительно неверен. Мне нужно будет увидеть, какое рычаги я должен изменить для рассматриваемого класса. Спасибо :) – Aren

12

Как всегда, используйте:

Debugger.Break() 
+1

бы с удовольствием, если бы я мог изменить конструктор ...... – Aren

+0

@Aren: Вы всегда можете просто написать код в 'global.asax' файла; P – leppie

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
  2. нагрузки sosex с помощью .load sosex
  3. Следующий вопрос командной !mbm *Code.Test..cctor*
  4. Отладчик перерывы на вызовите статический конструктор , после которого вы можете отправить !mk, чтобы получить CallStack

Вот выход из !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 

НТН

+0

Удачи вам в веб-приложении ... – leppie

+0

Действительно круто: o +1 – Aren

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 
       } 
      } 
     } 
    } 
} 
Смежные вопросы