イベントを発生させるメソッドの実装

今まで、イベントを発生させるメソッドを何も考えずに

public event EventHandler<HelloEventArgs> Hello;

protected virtual void OnHello(HelloEventArgs e)
{
    if (Hello != null)
    {
        Hello(this, e);
    }
}

と書いていたけど、どうやらこれはマズイみたい。スレッドセーフじゃない。

if (Hello != null)

を満たして

Hello(this, e);

に来るまでの間に、別のスレッドで全てのイベントハンドラが解除されたら NullReferenceException が発生してしまう。なので

public event EventHandler<HelloEventArgs> Hello;

protected virtual void OnHello(HelloEventArgs e)
{
    EventHandler<HelloEventArgs> tmp = Hello;
    if (tmp != null)
    {
        tmp(this, e);
    }
}

と書けば、Hello がもともと null のときは if の条件を満たさないし、別スレッドで Hello を null にされても tmp は null にならないので、 NullReferenceException は発生しない。