How does one go about publishing event in a safe way so that one could minimize the chance of exceptions? Let's say you have a class such as this:
public class MyClass
{
public event EventHandler MyEvent;
}
The first thing that comes to mind when you want to publish MyEvent would be to just invoke the delegate.
MyEvent(this, EventArgs.Empty);
The first issue that you would find is that if no one has subscribed to the event then just invoking the delegate would cause a null reference exception. So we need to check for null.
if ( MyEvent != null )
MyEvent(this, EventArgs.Empty);
This leads to another issue. Someone could unsubscribe from the event handler after we check for null which would lead to another null reference exception when we invoke the delegate. Since delegates are immutable we can copy the delegate to a variable and it will keep its state even if someone unsubscribes from the event. So we assign it to a variable, check the variable for null then invoke.
EventHandler handler = MyEvent;
if (handler != null)
handler(this, EventArgs.Empty);
That much code for invoking a delegate smells bad and needs to be moved to its own method. So we refactor using ExtractMethod and create an OnMyEvent method.
protected void OnMyEvent()
{
EventHandler handler = MyEvent;
if (handler != null)
handler(this, EventArgs.Empty);
}
Now that we have the method there is one hidden issue that most people don't realize could cause us problems which is compiler optimization. The JIT compiler might decide to optimize our method, removing our variable and just make the call directly to the event delegate leaving us open for another null reference exception. We can stop that from occurring by adding an attribute which will tell the compiler to not optimize the method.
[MethodImpl(MethodImplOptions.NoInlining)]
protected void OnMyEvent()
{
EventHandler handler = MyEvent;
if (handler != null)
handler(this, EventArgs.Empty);
}
This gives us a self contained safe and easy way to raise the event.