Add delegate to event – thread safety

If you don’t specify your own event add/remove handlers, the C# compiler generates this add handler (reconstructed by .NET Reflector):

public void add_MyEvent(EventHandler value)
{
    EventHandler handler2;
    EventHandler myEvent = this.MyEvent;
    do
    {
        handler2 = myEvent;
        EventHandler handler3 = (EventHandler) Delegate.Combine(handler2, value);
        myEvent = Interlocked.CompareExchange<EventHandler>(ref this.MyEvent, handler3, handler2);
    }
    while (myEvent != handler2);
}

and a remove handler that looks the same but with Delegate.Remove instead of Delegate.Combine.

Notice the use of Interlocked.CompareExchange? This prevents a race condition between updating the event’s backing field and reading from it. Thus, it is thread-safe.

Leave a Comment