Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it always safe to unsubscribe from an event inside the handler?

Tags:

c#

events

Lets say that I have this (incomplete) class, in which I raise an event without first assigning it to a variable to make it thread-safe:

public class Test
{
    public event EventHandler SomeEvent;

    void OnSomeEvent(EventArgs e)
    {
        if (SomeEvent != null)
            SomeEvent(this, e);
    }
}

Would it be safe to unsubscribe an event handler from itself, or could there be any problem similar to what would happen when removing items from a collection while enumerating it?

void SomeEventHandler(object sender, EventArgs e)
{
    testInstance.SomeEvent -= SomeEventHandler;
}
like image 410
Trisibo Avatar asked Oct 05 '15 14:10

Trisibo


2 Answers

To clarify the other answer a bit:

Events are based on delegates (in almost all cases). Delegates are immutable. This applies to multicast delegates, too.

When invoking an event the delegate is loaded and then invoked. If the field that the delegate is stored in is modified then this does not affect the already loaded delegate.

It's therefore safe to modify the event from the handler. Those changes will not affect the currently running invocation. This is guaranteed.

All of this only applies to events backed by a delegate. C# and the CLR support custom events that could do anything at all.

like image 117
usr Avatar answered Nov 15 '22 18:11

usr


It would be safe, however, just know it is not a guarantee that the code in SomeEventHandler will be executed only once. A race condition might occur if you have multithreaded code.

Edit: Unsubscribing from an event will, behind the scenes, combine delegates to produce a list of delegates. (Lots of details can be found on that article by Jon Skeet the man himself)

Note that the event uses locks to guarantee thread safety on the Delegate combination. Once you have combined a delegate to your event, you will have a resulting list of delegates. When raising an event, however, what is not guaranteed is that the latest version of the combined delegates will be used. (see Thread-safe events) but this is unrelated to the fact the event was un-hooked from the inside of the event.

I hope my edit provides enough clarification :)

like image 40
Fabio Salvalai Avatar answered Nov 15 '22 20:11

Fabio Salvalai