マルチスレッド環境で .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 が発生する可能性はありますか?