Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Events - Handler vs direct access? Why?

Tags:

c#

events

handler

SAMPLE CODE:

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));
    }
}

Why is it that I always see people creating assigning PropertyChanged to a "handler" instead of just using it?

like image 573
michael Avatar asked Oct 28 '11 20:10

michael


Video Answer


2 Answers

If you do it the simpler way, and a different thread removes the last handler from the event just inside your if, you'll get a null reference. (delegates are immutable)

By making a handler temporary, you prevent this, since you only check the field once.

If the event will never be unsubscribed to from multiple threads, you don't need the temporary.

like image 108
SLaks Avatar answered Oct 13 '22 02:10

SLaks


Did you ever actually see this happen?

Sure, this takes a fraction of second to bomb on my machine after starting it:

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) { }
}

It is a quick crash due to the relentlessly quick looping. In a real app this takes anywhere between a day and a year to crash. The odds that you'll catch it while debugging your code are very slim. If it does happen you'll go, "wtf? Let's try again" and not get it again.

like image 35
Hans Passant Avatar answered Oct 13 '22 02:10

Hans Passant