2010-12-16 15 views
5

Widziałem następujące wzór używany do realizacji INotifyPropertyChangedWzór do implementacji INotifyPropertyChanged?

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

public event PropertyChangedEventHandler PropertyChanged; 

Czy ktoś może mi wyjaśnić konieczność obsługi var = PropertyChanged zadanie przed sprawdzeniem go zerowa w porównaniu bezpośrednio sprawdzanie PropertyChanged == null bezpośrednio?

Dzięki

+0

możliwy duplikat [Dlaczego C# wymaga napisania zerowej kontroli za każdym razem, gdy uruchamiasz zdarzenie ?] (http://stackoverflow.com/questions/3102918/why-does-c-require-you-to-write-a-null-check-every-time-you-fire-an-event) – decyclone

+0

@decyclone , to nie jest dupe ... OP nie pyta, dlaczego musisz sprawdzić, czy program obsługi ma wartość null, ale dlaczego musisz użyć lokalnej kopii programu obsługi. –

+0

Czy ten wzorzec jest konieczny dla VB.NET? A może RaiseEvent sobie z tym poradzi? – MCattle

Odpowiedz

4

Eric Lippert wyjaśnia to szczegółowo w tym artykule na blogu: Events and races.

Zasadniczo chodzi o to, aby uniknąć sytuacji wyścigu w przypadku, gdy inny wątek anuluje ostatnią procedurę obsługi tego zdarzenia po sprawdzeniu PropertyChanged != null, ale przed faktycznym wywołaniem PropertyChanged. Jeśli utworzysz lokalną kopię programu obsługi, nie może się to zdarzyć (ale możesz zakończyć wywoływanie programu obsługi, który został właśnie anulowany)

+0

To od subskrybenta zależy, czy zajmie się sprawą, w której zostanie wywołana zaraz po tym, jak zostanie wyłączony z subskrypcji (bez względu na to, w którym źródle zdarzenia ten wyścig nie może być pominięty bez wyeliminowania wszystkich współbieżności). – Richard

0

W wielowątkowy świata, PropertyChanged może być ustawiona na null po if został oceniony.

1

Jest to bezpieczna metoda podnoszenia zdarzeń. Poprzez przypisywanie publicznie dostępnego zdarzenia PropertyChanged na miejscu przed jego użyciem, upewnij się, że nie będzie się różnić między instrukcją "if" a linią faktycznie podnoszącą zdarzenie.

Powiązane problemy