4

マルチスレッド環境で .NET イベントを処理する際の問題は、誰もが知っています。そのうちの 1 つは、ローカル変数にコピーせずにイベントを呼び出そうとした場合です。

if (MyEvent != null)
    MyEvent(this, EventArgs.Empty);

このような場合、あるスレッドが MyEvent != null をチェックした後、別のスレッドがイベントからサブスクライブ解除ハンドラーを取得すると、競合状態が発生する可能性があります。(その後、MyEventが発火しようとしており、ops.. NullRefException)

(J.Richter によって提案された) 解決策は、イベント ハンドラーをローカル変数にコピーすることです。

var handler = MyEvent;
if (handler != null)
    handler(this, EventArgs.Empty); 

これはうまくいきます

デリゲートは不変です。作成されたデリゲートの呼び出しリストは変更されません。

しかし、私が知っているように、AMD64 JIT は、ローカル コピーを無視してイベント ハンドラーの実際の値を読み取ることができるいくつかの最適化を行います。(記事は古いですが、そのような問題に関する実際の情報は見つかりません)。

では、そのような場合、実際に CLR JIT はどのように機能するのでしょうか? NullReferenceException が発生する可能性はありますか?

4

1 に答える 1