ホームページ > バックエンド開発 > C++ > C# でイベントをディスパッチするときに競合状態を回避するにはどうすればよいですか?

C# でイベントをディスパッチするときに競合状態を回避するにはどうすればよいですか?

Mary-Kate Olsen
リリース: 2025-01-03 17:03:41
オリジナル
217 人が閲覧しました

How to Avoid Race Conditions When Dispatching Events in C#?

イベントディスパッチにおける競合状態

C# のイベントは、次のコードを使用してディスパッチされることがよくあります:

public event EventHandler SomeEvent;
...
{
    ....
    if(SomeEvent!=null)SomeEvent();
}
ログイン後にコピー

ただし、マルチスレッド環境では、このアプローチは競合状態を引き起こす可能性があります。これがどのように起こるかは次のとおりです。

  1. スレッド 1 は SomeEvent が null でないかどうかを確認します。
  2. スレッド 2 は SomeEvent から唯一の登録されたデリゲートを削除します。
  3. スレッド 1 は次の処理に進みます。 SomeEvent を呼び出します。null 呼び出しにより例外が発生します。 list.

この同時実行性の問題に対処するためのベスト プラクティスは、null をチェックする前に呼び出しリストを一時変数にコピーすることです。

protected virtual void OnSomeEvent(EventArgs args) 
{
    EventHandler ev = SomeEvent;
    if (ev != null) ev(this, args);
}
ログイン後にコピー

このアプローチはスレッドセーフです。なぜなら:

  • Delegate.Combine と Delegate.Remove は、代わりに新しいデリゲート インスタンスを返します。既存のものを変更します。
  • .NET でのオブジェクト参照の割り当てはアトミックです。
  • イベント アクセサー (追加/削除) は同期されます。

呼び出しをコピーすることにより、リストにあるように、コピーの取得後にイベント ハンドラーが削除された場合でも、イベント ハンドラーが確実に呼び出されます。ただし、この解決策は、廃止されたイベント ハンドラーに関する潜在的な状態の問題には対処していないことに注意することが重要です。

以上がC# でイベントをディスパッチするときに競合状態を回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート