多くの開発者が呼び出したいときに、直接呼び出すのではなく、Event
という名前のローカル変数に割り当てて呼び出すのを見てきました。イベントを直接呼び出さないのはなぜですか?handler
handler
Event
private void OnSomethingChanged(EventArgs e)
{
if (SomethingEvent != null)
{
SomethingEvent(this, e);
}
}
多くの開発者が呼び出したいときに、直接呼び出すのではなく、Event
という名前のローカル変数に割り当てて呼び出すのを見てきました。イベントを直接呼び出さないのはなぜですか?handler
handler
Event
private void OnSomethingChanged(EventArgs e)
{
if (SomethingEvent != null)
{
SomethingEvent(this, e);
}
}
あなたが投稿したコードは、基本的にスレッドセーフではありません。チェック後、呼び出し前に、最終サブスクライバーが別のスレッドでサブスクライブを解除すると、が取得されます。if
NullReferenceException
1つのオプションは、拡張メソッドを作成することです。
public static void NullSafeInvoke(this EventHandler handler,
object sender, EventArgs e)
{
if (handler != null)
{
handler(this, e);
}
}
次に、次のように書くことができます。
private void OnSomethingChanged(EventArgs e)
{
SomethingEvent.NullSafeInvoke(this, e);
}
おそらくEventHandler<T>
、別のオーバーロードも必要になるでしょう。
イベントがコピーされない場合、競合状態になる可能性があります(マルチスレッドアプリケーションのみに関連)。
null
チェックの直後に1つのスレッドがイベントのサブスクライブを解除し、サブスクライブされていないスレッドがある場合は、が取得されますNullReferenceException
。