2012-04-03 13 views
5

Nell'attuare l'interfaccia INotifyPropertyChanged nella sua forma più semplice, la maggior parte delle persone sembrano implementare in questo modo ::InotifyProperyChanged: perché l'assegnazione aggiuntiva?

public virtual void OnPropertyChanged(string propertyName) 
{ 
    var propertyChanged = PropertyChanged; 
    if (propertyChanged != null) 
    { 
     propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

La mia domanda è: perché l'assegnazione supplementare di var propertyChanged = PropertyChanged;? È solo una questione di preferenza, o c'è una buona ragione per questo? Sicuramente quanto segue è altrettanto valido?

public virtual void OnPropertyChanged(string propertyName) 
{ 
    if (PropertyChanged != null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
+1

http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety –

risposta

4

L'assegnazione a una variabile temporanea rimuove la possibilità di una condizione di competizione tra l'assegno nullo e l'ultimo abbonato evento, l'annullamento dell'iscrizione. Consulta le linee guida sugli eventi .NET here.

Snip:

// Make a temporary copy of the event to avoid possibility of 
    // a race condition if the last subscriber unsubscribes 
    // immediately after the null check and before the event is raised. 
    EventHandler<CustomEventArgs> handler = RaiseCustomEvent; 
+0

Ok, quindi è una questione di sicurezza del thread. Ma in un'app MVVM, tutte queste chiamate sono fatte dal Dispatcher principale, quindi non è davvero un problema, vero? – Per

+0

Non necessariamente. Sì, le viste aggiungeranno/rimuovono gli abbonati per i loro collegamenti sul thread principale della GUI. Ma potresti avere altri modelli, creati su un thread non GUI, che si iscrivono alle modifiche sulla proprietà di ViewModel. Naturalmente, questa potrebbe non essere una buona pratica di progettazione e forse quei Modelli dovrebbero ricevere notifiche tramite un Aggregatore di eventi. –

1

E 'per gli ambienti multithread, in cui qualche altro thread potrebbe impostare l'evento per null prima che venga eseguito.

Utilizzando la variabile locale questo viene impedito e i delegati assegnati verranno comunque chiamati.

1

In un'applicazione con multithreading, è possibile che (nel tuo secondo esempio) tra verificare se PropertyChanged != null (supponiamo che non sia null) e in realtà chiamare il delegato, il thread è preceduto da un altro che sta annullando la registrazione lo ultimo listener di eventi dal delegato. Quindi, quando il thread originale riprende e chiama PropertyChanged(this, new PropertyChangedEventArgs(propertyName));, sarà ora nullo e verrà generato un NullReferenceException.

Problemi correlati