Raising custom events

How do you define and raise custom events in C#?

public event EventHandler<TEventArgs> MyEvent;
protected virtual OnMyEvent(TEventArgs e)
  if (MyEvent != null)
    MyEvent(this, e);

This is fine, but now in a multi-threading environment, where things get nasty: suppose that one thread compares MyEvent to null, finds it is not null, then another thread unsubscribes the last listener from the event, and MyEvent becomes null. Boom – an exception will be thrown when MyEvent gets eventually called by the first thread.

MSDN examples use this approach:

protected virtual OnMyEvent(TEventArgs e)
  var myEvent = MyEvent;
  if (myEvent != null)
    myEvent(this, e);

Having a copy of the event handler list is a lot better: the exception doesn’t arise anymore.

But as usual with multi-threading, doing some thing to resolve an issue, will always generate another issue, maybe occurring more rarely. See this article for details.

Still, I find that ensuring the exception doesn’t occur after the null check is very important to do, and if your habits include it, you’re generally more safe when multi-threading is added into your application than otherwise.

Moreover, I think C# next should also add the copy and if internally itself, whenever one calls MyEvent() in code. It’s certain that this will hide some things occurring internally from the developer’s eye, but so are many other things in latest .NET versions (see async and await, for example!)

And also, always do the same with properties:

var myObjectPropertyValue = myObject.MyProperty;
if (myObjectPropertyValue != null)

I’m sure you usually copy the property value object before accessing MySubProperty as a “common sense” rule, so don’t forget to do the same with events.

Update: with the latest C# additions, it’s possible to do syntax sugaring (at least) this way:

MyEvent?.Invoke(this, myEventArgs);

About Sorin Dolha

My passion is software development, but I also like physics.
This entry was posted in .NET, C# and tagged , , . Bookmark the permalink.

Add a reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s