2015-04-23 161 views
2

我所有我见过的在C#中的事件的样本是触发该事件被写成注意到:触发事件

PropertyChangedEventHandler handler = PropertyChanged; 
if(handler != null) 
    handler(this, new PropertyChangedEventArgs(propertyName)); 

那是什么,只是写之间的不同:

if(PropertyChanged != null) 
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
+4

原因是作为问题的一部分陈述在这里:http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety还有一个链接到Eric Lippert的博客文章解释它:http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx – Dirk

+1

@JenishRabadiya:它可以为null。这是一个事件。 –

+0

@PatrickHofman是的你是对的。它来自'INotifyPropertyChanged'接口。 –

回答

4

在第二种情况下,如果您正在运行多线程,则PropertyChanged的值可能会在if与invoke之间发生变异。不推荐。

您也可以尝试初始化事件处理程序有一个空的处理程序是这样的:

public EventHandler<PropertyChangeEventArgs> PropertyChanged = (s, e) => { }; 

,这意味着它永远不会为空,这样你就可以只启动它是。

+0

*这意味着它永远不会为空*除非您将其设置为。不要忘记你可以在声明事件的类中明确地将其设置为null。 –

8

在你的第二个例子中,你调用PropertyChanged的获得者两次。在多线程环境中,可能会在两次调用之间更改值。

在第一个示例中,通过先制作本地副本,可以防止这种情况发生。

+0

但是在第一种情况下(代码片段),如果某个线程为'PropertyChanged'分配空值,则不会将其分配给'处理程序'实例,因为委托的行为类似于引用类型。 –

+0

@JenishRabadiya处理程序仍然会指向最初的代表。将代理想象成一个数组(要调用的方法)。如果将先前指向数组的一个变量设置为空,则不会更改指向同一数组的另一个变量。 – GvS

+0

当我阅读[msdn文档](https://msdn.microsoft.com/en-us/library/ms173172.aspx)时,这似乎让我感到困惑。文档引号“委托类型派生自.NET Framework中的委托类”,代表是可能的参考类型。 –