Prevent subscribing to an event twice in c#

Events in C# use the observer pattern, where an observer can subscribe itself to event generated by a subject. Within C# the observer can subscribe itself multiple times to the subject. When the subject fires the event, the observer gets multiple events.

The best way to prevent is to be keen on the life-cycle of your events; subscribe at the right place at an event en un-subscribe from the event also at the right place. How can we have a defensive mechanism, that prevents us subscribing multiple times at an event?

Take for example the following subject:

public class ImageGenerator
{
    public event EventHandler OnNewImage; 
}

We can now have the following observer:

public class CallingClass
{
  public CallingClass()
  {
    ImageGenerator eventClass = new ImageGenerator();
    eventClass.OnNewImage += HandleNewImage;
  }

  private void HandleNewImage(object sender, EventArgs e)
  { // Handle the event here... }
}

You can now simply subscribe twice by adding changing the constructor of CallingClass like this:

ImageGenerator eventClass = new ImageGenerator();
eventClass.OnNewImage += HandleNewImage;
eventClass.OnNewImage += HandleNewImage;

Nothing will detect this and when the OnNewImage event is fired, the HandleNewImage will be called twice.

By searching on the internet, I stumbled upon this piece of code which checks if the observer has itself already registered. If not, it will be added to the subscription, otherwise ignored. The subject will look like this:

public class ImageGenerator
{
    private event EventHandler NewImageEvent;
    public event EventHandler OnNewImage
    {
       add
       {
          if (NewImageEvent == null || !NewImageEvent.GetInvocationList().Contains(value))
          {
             NewImageEvent += value;
          }
          else
          {
             // Do here some logging
          }
        }
        remove
        {
            NewImageEvent -= value;
        }
     }
}

I think it’s wise to add some logging or make yourself somehow aware if you subscribed twice on the event. In this way you can fix design issues within your code.

Posted in C# by Bruno at December 20th, 2017.

Leave a Reply