События - Обработчик против прямого доступа? Зачем? - PullRequest
9 голосов
/ 29 октября 2011

КОД ОБРАЗЦА:

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 ]

15 голосов
/ 29 октября 2011

Если вы сделаете это более простым способом, а другой поток удалит последний обработчик из события прямо внутри вашего if, вы получите нулевую ссылку.(делегаты являются неизменяемыми)

Делая временным handler, вы предотвращаете это, поскольку проверяете поле только один раз.

Если событие никогда не будет отписаноиз нескольких потоков вам не нужно временное.

5 голосов
/ 29 октября 2011

Вы когда-нибудь видели это на самом деле?

Конечно, это занимает долю секунды, чтобы бомбить мою машину после запуска:

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? Давайте попробуем еще раз" и не получим его снова.

...