27

だから、ここに私のクラスの1つからの抜粋があります:

    [ThreadStatic]
    readonly static private AccountManager _instance = new AccountManager();

    private AccountManager()
    {
    }

    static public AccountManager Instance
    {
        get { return _instance; }
    }

ご覧のとおり、これはスレッドごとにシングルトンです。つまり、インスタンスは ThreadStatic 属性でマークされています。インスタンスは、静的構築の一部としてもインスタンス化されます。

では、Instance プロパティを使用しようとすると、ASP.NET MVC アプリケーションで NullReferenceException が発生する可能性はありますか?

4

5 に答える 5

38

MSDN ThreadStaticAttribute の引用:

ThreadStaticAttribute でマークされたフィールドには初期値を指定しないでください。このような初期化は、クラス コンストラクターの実行時に 1 回だけ行われ、1 つのスレッドにしか影響しないためです。初期値を指定しない場合、フィールドが値型の場合は既定値に初期化され、参照型の場合は null 参照 (Visual Basic では Nothing) に初期化されます。

于 2010-01-11T17:19:40.857 に答える
13

これはThreadStatic属性の紛らわしい部分です。スレッドごとに値を作成しますが、初期化コードはいずれかのスレッドでのみ実行されます。この値にアクセスする他のすべてのスレッドは、初期化コードの結果ではなく、その型のデフォルトを取得します。

値の初期化の代わりに、初期化を行うプロパティにラップします。

[ThreadStatic]
readonly static private AccountManager _instance;

private AccountManager()
{
}

static public AccountManager Instance
{
  get 
  { 
    if ( _instance == null ) _instance = new AccountManager();
    return _instance; 
  }
}

_instanceはスレッドごとに一意であるため、プロパティでロックする必要はなく、他の遅延初期化値と同様に扱うことができます。

于 2010-01-11T17:20:23.103 に答える
8

[ThreadStatic]ここで古典的な「101」をヒットしました。

としてマークされていても、静的初期化子は 1 回しか起動しない[ThreadStatic]ため、他のスレッド (最初のスレッドを除く) はこれが初期化されていないことを認識します。

于 2010-01-11T17:20:47.237 に答える
1

何が起こっているのかというと、静的フィールドは一度だけ初期化されているため、別のスレッドがフィールドを読み取ろうとすると、_instance を再度初期化できないため、(デフォルト値であるため) null になります。それは単なる考えですが、私は完全に外れている可能性がありますが、それが起こっていると思います.

于 2010-01-11T17:20:14.710 に答える
0

ThreadStaticAttribute でマークされた静的フィールドは、スレッド間で共有されません。実行中の各スレッドは、フィールドの個別のインスタンスを持ち、そのフィールドの値を個別に設定および取得します。フィールドが別のスレッドでアクセスされると、別の値が含まれます。

于 2013-11-12T11:21:47.433 に答える