事件 - 处理程序与直接访问?为什么?

时间:2011-10-28 20:13:20

标签: c# events handler

示例代码:

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String propertyName) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) 
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

VS

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String propertyName) 
{ 
    if (PropertyChanged!= null) 
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

为什么我总是看到人们创建将PropertyChanged分配给“处理程序”而不是仅使用它?

2 个答案:

答案 0 :(得分:15)

如果以更简单的方式执行此操作,并且另一个线程从if内的事件中删除最后一个处理程序,则会获得空引用。 (代表是不可变的)

通过临时设置handler,可以防止这种情况发生,因为您只检查一次字段。

如果事件从不从多个线程取消订阅,则不需要临时。

答案 1 :(得分:5)

  

你真的看到过这种情况吗?

当然,启动它后,我的机器上只需要一秒钟的时间炸弹:

using System;
using System.Threading;

class Program {
    static void Main(string[] args) {
        EventHandler anEvent = null;
        var t1 = ThreadPool.QueueUserWorkItem((w) => {
            for (; ; ) {
                anEvent += Test;
                anEvent -= Test;
            }
        });
        var t2 = ThreadPool.QueueUserWorkItem((w) => {
            for (; ; ) {
                if (anEvent != null) anEvent(null, null);
            }
        });
        Console.ReadLine();
    }

    static void Test(object sender, EventArgs e) { }
}

由于无情的快速循环,这是一个快速崩溃。在真实的应用程序中,这需要一天到一年的时间才能崩溃。在调试代码时你会发现它的几率很小。如果确实发生了,你会去,“wtf?让我们再试一次”,而不是再次得到它。