Null チェックを使用したイベント ディスパッチのマルチスレッドの安全性
イベントベースのプログラミングでは、イベントによってさまざまなオブジェクトが通信し、特定の出来事に反応できるようになります。以下に示すように、イベント ハンドラー デリゲートの null チェックを使用してイベントをディスパッチするのが一般的です:
public event EventHandler SomeEvent; ... { .... if(SomeEvent!=null)SomeEvent(); }
ただし、マルチスレッド環境では、別のスレッドがイベントの呼び出しリストを変更する可能性がある競合状態が発生する可能性があります。 null チェックと呼び出しの間。これにより、例外や不正な動作が発生する可能性があります。
マルチスレッドの問題への対処
これを軽減するには、イベント ハンドラー デリゲートをイベント内のローカル変数に割り当てることをお勧めします。以下に示すように、ディスパッチ メソッドを実行します。
protected virtual void OnSomeEvent(EventArgs args) { EventHandler ev = SomeEvent; if (ev != null) ev(this, args); }
これを実行すると、その後のSomeEvent イベント ハンドラー リストは、ev 変数に格納されているコピーには影響しません。これにより、途中でイベント ハンドラー リストが変更された場合でも、イベントが正しく呼び出されることが保証されます。
このソリューションは、マルチスレッド イベント処理の 1 つの側面のみに対応していることに注意することが重要です。機能しなくなったイベント ハンドラーや、コピーが取得された後にサブスクライブするイベント ハンドラーは完全には考慮されていません。この分野のベスト プラクティスに関する包括的なガイドについては、Eric Lippert のブログ エントリおよびこのトピックに関する StackOverflow ディスカッションを参照してください。
以上がNull チェックを使用してイベントをディスパッチするときにマルチスレッドの安全性を確保するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。