C#的空条件委托调用线程是否安全?

amn*_*sia 5 c# multithreading

这就是我一直写的事件提升者; 例如PropertyChanged:

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

然而,在最新的Visual Studio中,灯泡thingamabob建议将代码简化为:

    private void RaisePropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
Run Code Online (Sandbox Code Playgroud)

虽然我总是赞成简化,但我想确保这是安全的.在我的原始代码中,我将处理程序分配给变量以防止订阅者在空检查和调用之间处置的竞争条件.在我看来,新的简化形式将遭受这种情况,但我想看看是否有人可以确认或否认这一点.

ang*_*son 7

它与它替换的代码(你的第一个例子)一样是线程安全的,因为它只是使用一个隐藏变量做同样的事情.


小智 6

来自MSDN:

新方法是线程安全的,因为编译器只生成一次评估PropertyChanged的代码,将结果保存在临时变量中.您需要显式调用Invoke方法,因为没有空条件委托调用语法PropertyChanged?(e).有太多模糊的解析情况允许它.

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