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

mic*_*ael 9 c# events handler

示例代码:

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

VS:

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

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

SLa*_*aks 15

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

通过handler临时,您可以防止这种情况,因为您只需检查一次该字段.

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

  • @Nikola:还有:*我只是认为,在几个线程中以惊人的速度添加/删除事件处理程序,以便在恰当的时刻提供足够的线程切换概率*,这样可怕的代码可能很小.那么你不能写很多多线程代码.这被称为竞争条件,它一直在发生. (2认同)

Han*_*ant 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) { }
}
Run Code Online (Sandbox Code Playgroud)

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