In order to raise an event we use a method OnEventName like this:
protected virtual void OnSomethingHappened(EventArgs e)
{
EventHandler handler = SomethingHappened;
if (handler != null)
{
handler(this, e);
}
}
But what is the difference with this one ?
protected virtual void OnSomethingHappened(EventArgs e)
{
if (SomethingHappened!= null)
{
SomethingHappened(this, e);
}
}
Apparently the first is thread-safe, but why and how ?
It’s not necessary to start a new thread ?
There is a tiny chance that
SomethingHappenedbecomesnullafter the null check but before the invocation. However,MulticastDelagates are immutable, so if you first assign a variable, null check against the variable and invoke through it, you are safe from that scenario (self plug: I wrote a blog post about this a while ago).There is a back side of the coin though; if you use the temp variable approach, your code is protected against
NullReferenceExceptions, but it could be that the event will invoke event listeners after they have been detached from the event. That is just something to deal with in the most graceful way possible.In order to get around this I have an extension method that I sometimes use:
Using that method, you can invoke the events like this: