Is C#'s null-conditional delegate invocation thread safe? [duplicate]

拈花ヽ惹草 提交于 2021-01-02 08:16:33

问题


This is how I have always written event raisers; for example PropertyChanged:

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string name)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(name));
    }

In the latest Visual Studio, however, the light bulb thingamabob suggested simplifying the code to this:

    private void RaisePropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

Although I'm always in favor of simplification, I wanted to be sure this was safe. In my original code, I assign the handler to a variable to prevent a race condition in which the subscriber could become disposed in between the null check and the invocation. It seems to me that the new simplified form would suffer this condition, but I wanted to see if anyone could confirm or deny this.


回答1:


from MSDN:

The new way is thread-safe because the compiler generates code to evaluate PropertyChanged one time only, keeping the result in temporary variable. You need to explicitly call the Invoke method because there is no null-conditional delegate invocation syntax PropertyChanged?(e). There were too many ambiguous parsing situations to allow it.

https://msdn.microsoft.com/en-us/library/dn986595(v=vs.140).aspx




回答2:


It is as thread-safe as the code it replaced (your first example) because it is doing the exact same thing, just using a hidden variable.




回答3:


Internally .net framework uses interlock.CompareExchange when you subscribe for an event. This means you already has memory barrier there. To be thread safe you need to use Volatile.Read when accessing your event handler (it applies implicit aquire memory barrier)

Volatile.Read(ref PropertyChanged)?.Invoke(this, new PropertyChangedEventArgs(name))

Source: CLR via C#

Other source: https://codeblog.jonskeet.uk/2015/01/30/clean-event-handlers-invocation-with-c-6/



来源:https://stackoverflow.com/questions/36425898/is-cs-null-conditional-delegate-invocation-thread-safe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!