2

I saw a lot of the following usage of event handler. Why they assign the handler to a local variable and then use the local variable?

event EventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)
{
    var temp = PropertyChanged;
    if (temp != null)
        temp(this, new PropertyChangedEventArgs(propertyName));
    // why not just "if (PropertyChanged != null) PropertyChanged(...)" 
}
ca9163d9
  • 27,283
  • 64
  • 210
  • 413

4 Answers4

4

The temporary variable ensures thread safety, because between the check and actual call other thread may unsubscribe from the event which will result in NullReferenceException.

Eric Lippert has a great article on this

Yurii
  • 4,811
  • 7
  • 32
  • 41
  • Can I ignore the pattern if I'm writing a winforms application which which only assigns the event handlers in the form loading events? The background workers are used to assign the data sources of controls though. – ca9163d9 Jun 26 '14 at 06:58
  • +1 thanks for the link to the article – Tim Schmelter Jun 26 '14 at 07:02
  • @dc7a9163d9 mentioning background workers means that you already do some multithreading, so I'd suggest sticking with the temp variable. – Yurii Jun 26 '14 at 07:12
  • I will use the pattern no matter what. Just curious of if it's safe if the background workers never unsubscribe the event handlers. – ca9163d9 Jun 26 '14 at 07:34
0

Because the PropertyChanged could change as a result of other thread's operations; in particular, it can be set to null just between the null check and the call.

BlackBear
  • 22,411
  • 10
  • 48
  • 86
0

Because in a multi threaded environment if the last subscriber of the event unsubscribed after the if but before the invocation you will get a NullRefrenceExecption. By copying the delegate locally first it can no longer be modified by unsubscriptions.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
0

Imagine this:

if (PropertyChanged)
  PropertyChanged(...)

now just after the if the OS skips threads and the new one will remove the only subscription. After this PropertyChanged is null and you are in trouble.

Random Dev
  • 51,810
  • 9
  • 92
  • 119