Defensive Event Publishing

by bill 5/26/2008 3:48:00 PM

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.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Powered by BlogEngine.NET 1.3.1.0
Theme by Mads Kristensen

About the author

Name of author Bill Rodenbaugh
I bang on the keyboard and somehow the end result turns into some kind of thing that sometimes does something.

E-mail me Send mail
View Bill Rodenbaugh's profile on LinkedIn

Calendar

<<  August 2008  >>
MoTuWeThFrSaSu
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

View posts in large calendar

Recent comments

Authors

Categories

None


Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Sign in