今まで、イベントを発生させるメソッドを何も考えずに
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 は発生しない。