Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是C#';s null条件委托调用线程安全?_C#_Multithreading - Fatal编程技术网

是C#';s null条件委托调用线程安全?

是C#';s null条件委托调用线程安全?,c#,multithreading,C#,Multithreading,这就是我一直以来写的事件提倡者;例如,PropertyChanged: public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string name) { var handler = PropertyChanged; if (handler != null) handler(this, n

这就是我一直以来写的事件提倡者;例如,PropertyChanged:

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string name)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(name));
    }
然而,在最新的Visual Studio中,灯泡thingamabob建议将代码简化为:

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

虽然我一直支持简化,但我想确保这是安全的。在我的原始代码中,我将处理程序分配给一个变量,以防止出现竞态条件,在这种竞态条件下,订阅者可能在null检查和调用之间被释放。在我看来,新的简化表单可能会出现这种情况,但我想看看是否有人可以确认或否认这一点。

它与它所替换的代码(您的第一个示例)一样具有线程安全性,因为它只使用了一个隐藏变量,执行完全相同的操作。

来自MSDN:

新方法是线程安全的,因为编译器生成代码 评估属性仅更改一次,并将结果保留在 临时变量。您需要显式调用Invoke方法 因为没有空的条件委托调用语法 属性已更改?(e)。有太多模棱两可的解析情况 允许它


在内部.net framework在订阅事件时使用interlock.CompareExchange。这意味着你已经有了记忆障碍。为了线程安全,您需要在访问事件处理程序时使用Volatile.Read(它应用隐式获取内存屏障)

Volatile.Read(ref PropertyChanged)?.Invoke(这个,新的PropertyChangedEventArgs(名称))

资料来源:

其他来源: