7

ここで、クラスの1つの静的コンストラクターが呼び出される前に呼び出されるという問題に遭遇しています。(つまり、DI/IoC が設定されておらず、サービス ロケーターから null/例外が返されています)。

残念ながら、私は静的コンストラクターをあまり制御できません。なぜ DI/IoC のセットアップに依存しているのかを聞かないでください。

私のアプリでは、IoC の準備が整う前に、このクラス static またはそれ以外を参照する必要はありませんが、静的コンストラクターはとにかく実行されています。

コンストラクターが実行された原因となった行を特定する簡単な方法はありますか? 注: static constructorASP.NET のリモート デバッガーが Web サーバー (Global.asax.cs) に接続できるようになる前に、これがすべて発生するため、ブレークポイントを設定できません。

4

5 に答える 5

19

いつものように、次を使用します。

Debugger.Break()
于 2011-02-01T19:52:49.493 に答える
3

これは、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スタックを取得するために発行できます

!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

于 2011-02-01T20:15:13.173 に答える
1

静的コンストラクターがいつ実行されるかを制御することはできません。コンストラクターから静的なInitialize()関数に何をしていても移動します。準備ができたらいつでも電話してください。静的コンストラクターがいつ実行されるかに依存しないでください。

このリンクを確認してください

静的コンストラクターには次のものがあります。

プロパティ:

最初のインスタンスが作成される前、または静的メンバーが参照される前に、クラスを初期化するために静的コンストラクターが自動的に呼び出されます。

静的コンストラクターを直接呼び出すことはできません。

ユーザーは、静的コンストラクターがプログラムで実行されるタイミングを制御できません。

于 2011-02-01T19:53:30.213 に答える
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
                }
            }
        }
    }
}
于 2011-02-01T20:46:54.357 に答える