Отслеживание статического выполнения конструктора

StackOverflow https://stackoverflow.com/questions/4867253

Вопрос

Я сталкиваюсь с проблемой, где статический конструктор одного из моих классов называется до этого. (IE, DI/IOC не настроен, и он получает нулевые/исключения обратно от локатора службы).

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

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

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

Это было полезно?

Решение

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

Проверь это ссылка на сайт

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

характеристики:

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

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

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

Другие советы

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

Debugger.Break()

Это можно сделать с помощью 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

Hth

Может, вам следует пропустить, используя статический конструктор? Это обязательно?

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
                }
            }
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top