C#: Thread-safe events

后端 未结 2 537
借酒劲吻你
借酒劲吻你 2020-12-18 08:00

Is the implementation below thread-safe? If not what am I missing? Should I have the volatile keywords somewhere? Or a lock somewhere in the OnProcessingC

相关标签:
2条回答
  • 2020-12-18 08:33

    You need to lock when you fetch the handler too, otherwise you may not have the latest value:

    protected void OnProcessingCompleted(ProcessCompletedEventArgs e)
    {
        EventHandler<ProcessCompletedEventArgs> handler;
        lock (completedEventLock) 
        {
            handler = ProcessCompleted;
        }
        if (handler != null)
            handler(this, e);
    }
    

    Note that this doesn't prevent a race condition where we've decided we're going to execute a set of handlers and then one handler unsubscribed. It will still be called, because we've fetched the multicast delegate containing it into the handler variable.

    There's not a lot you can do about this, other than making the handler itself aware that it shouldn't be called any more.

    It's arguably better to just not try to make the events thread-safe - specify that the subscription should only change in the thread which will raise the event.

    0 讨论(0)
  • 2020-12-18 08:53

    There is no need for the private ProcessCompleted member to be an event - it could just be a field: private EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - inside the class it always goes straight to the field, so the event stuff is lost anyway.

    The approach you've shown with an explicit lock object isn't much more thread-safe than just having a field-like event (i.e. public event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - the only difference is that you aren't locking "this" (which is a good thing - you should ideally avoid locking on this).. The "handler variable" approach is the right one, but there are still side-effects you should be aware of.

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