实现INotifyPropertyChanged的模式是什么?

7
我见过以下模式用于实现INotifyPropertyChanged。

我曾经看到以下模式被用来实现INotifyPropertyChanged:

private void NotifyPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public event PropertyChangedEventHandler PropertyChanged;

有人能解释一下在检查PropertyChanged是否为空之前,var handler = PropertyChanged赋值的必要性吗?为什么不能直接检查PropertyChanged == null呢?
谢谢。

@decyclone,这不是重复的问题... OP并不是在问为什么必须检查处理程序是否为空,而是为什么需要使用处理程序的本地副本。 - Thomas Levesque
这个模式在VB.NET中是必需的吗?还是RaiseEvent会自动处理这个问题? - MCattle
3个回答

4
Eric Lippert在他的博客文章中详细解释了这一点:事件和竞争条件

基本上,这个想法是为了避免竞争条件。如果另一个线程在你检查PropertyChanged != null之后,但在你实际调用PropertyChanged之前取消订阅了此事件的最后一个处理程序,则会出现这种情况。如果你制作一个局部副本处理程序,则不会发生这种情况(但你可能会调用刚被取消订阅的处理程序)。


由订阅者处理在取消订阅后立即调用的情况取决于它(无论事件源如何,如果不消除所有并发,就无法避免这种竞争)。 - Richard

1

这是一种线程安全的事件触发方法。在使用公共可访问的 PropertyChanged 事件之前,将其本地分配,以确保在“if”语句和实际引发事件的行之间不会有任何差异。


0
在多线程世界中,在评估完if语句后,PropertyChanged属性可能会被设置为null。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接