Add delegate to event - thread safety

后端 未结 3 1733
南笙
南笙 2020-11-30 07:43

It is possible to execute the following code from multiple threads simultaneously.

this._sequencer.Completed += OnActivityFinished;

Is it t

相关标签:
3条回答
  • 2020-11-30 07:56

    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.

    0 讨论(0)
  • 2020-11-30 07:58

    for field-like events adding/removing of handlers is thread-safe. From spec:

    When compiling a field-like event, the compiler automatically creates storage to hold the delegate, and creates accessors for the event that add or remove event handlers to the delegate field. In order to be thread-safe, the addition or removal operations are done while holding the lock (§8.12) on the containing object for an instance event, or the type object (§7.6.10.6) for a static event.

    However it is true for C# 3.0 and lesser, in C# 4.0 compiler generates lock-free implementation using Interlocked routines (but spec remains the same - bug?)

    In custom implementations no one can tell exactly... except maybe the author of code :)

    0 讨论(0)
  • 2020-11-30 08:15

    It depends on the implementation of the event, to be honest.

    The field-like events generated by the C# compiler are thread-safe, but if it's a custom event, who knows?

    Note that in a multi-threaded app you should expect a race condition between adding/removing a handler and the event firing... for example, the event may start to fire, you could then unsubscribe, and your handler would still be called after that unsubscription.

    0 讨论(0)
提交回复
热议问题