Planning the Spontaneous

It's more than just a blueprint.

ConfusedEventHandler += new ConfusedEventHandler(Me.Confused);

Posted by Robert Chow on 20/01/2010

… Or at least that’s how I first felt when I started looking at event handling in .NET.

And I still do slightly – I’ve literally just looked at this 10 minutes ago, and I’m writing this down now while it’s still fresh in my head.

Observer Pattern

The observer pattern uses the notion of an Observer interface.  The state of each object that implements this can be updated through the interface.  The idea of using this interface allows a publisher to update all the objects in one swift movement.  Obviously, only those that are referenced by the publisher can be updated – those that are, are known as subscribers.  This design pattern is also a subset of the publish/subscribe pattern – any object that is subscribed will recieve any notifications sent by the publisher.

Publish/Subscribe.  A publisher sends events to subscribers.  This image has been taken from http://msdn.microsoft.com/en-us/library/ms978603.aspx.

So yesterday, I set about creating my own observable pattern implementation.  Yet today I learnt that there is a .NET implementation using events.

Event Handling

So with a little help from Microsoft and a lot more help from CodeProject, I’m going to try and explain to myself how to use them.

We start of with declaring the publisher.  The publisher contains a list of all the methods that should be invoked when an event is recieved.  This is done using 2 keywords and the name.

event EventHandler eventHandler;

event – declares that this is an event handler.
EventHandler – this is the default delegate type for event handlers.  This 2nd keyword must always be a delegate type it seems.

To add a subscriber, this is relatively simple.

eventHandler += new EventHandler(method);

+= – this symbol implies that we are wanting to subscribe a method to the event handler.  Similarly, to unsubscribe use the -= operator instead.
method – this is the method to be invoked when the publisher recieves an event to be sent on.

So now that we have a publisher and subscribers, lastly is to send an event to the publisher so it can pass it on to the subscribers.

eventHandler(sender, new EventArgs());

sender – the object that sent the event.  This is not compulsory and can be null.
new EventArgs() – event arguments for the event just occurred.  Again, this is not compulsory and can be null.  The methods subscribed to the publisher can always be invoked regardless of event arguments.

It’s actually fairly easy really once you get your head around it – at first I got hurrendously confused because I kept seeing “event” everywhere.

And of course, the sample I’ve just shown is fairly useless – it’s a lot more useful when you use your own delegate type as the event handler in conjunction with your own event arguments – most probably derived from EventArgs.

Increase Number Event

Below is a simple demo I’ve made just to make it a little more understandable, and it was also particularly useful when I was trying to figure it all out.  It uses a publisher, numberIncreasedEventHandler, whereby the Number objects n27, n39, n52 all have their Increase method subscribed.  This is invoked during Run, passing on an IncreaseNumberEventArgs which increases each object by the number contained in the argument.

public delegate void IncreaseNumberEventHandler(object sender, IncreaseNumberEventArgs e);

public class IncreaseNumberEventArgs : EventArgs
{
public int Increase;

public IncreaseNumberEventArgs(int increase)
{
this.Increase = increase;
}
}

public class Program
{
public static event IncreaseNumberEventHandler numberIncreasedEventHandler;

public static void Main(string[] args)
{
Number n27 = new Number(27);
Number n39 = new Number(39);
Number n52 = new Number(52);
numberIncreasedEventHandler += new IncreaseNumberEventHandler(n27.Increase);
numberIncreasedEventHandler += new IncreaseNumberEventHandler(n39.Increase);
numberIncreasedEventHandler += new IncreaseNumberEventHandler(n52.Increase);
Run();
}

public static void Run()
{
for (int i = 0; i < 10; ++i)
{
numberIncreasedEventHandler(null, new IncreaseNumberEventArgs(i));
}
}
}

public class Number
{
int number;
string name;

public Number(int initialNumber)
{
this.number = initialNumber;
this.name = “n” + initialNumber;
}

public void Increase(object o, IncreaseNumberEventArgs e)
{
Console.WriteLine(name + “: “ + number + ” increased by “ + e.Increase + ” to “ + (number += e.Increase));
}
}

And the output:

n27: 27 increased by 0 to 27
n39: 39 increased by 0 to 39
n52: 52 increased by 0 to 52
n27: 27 increased by 1 to 28
n39: 39 increased by 1 to 40
n52: 52 increased by 1 to 53
n27: 28 increased by 2 to 30
n39: 40 increased by 2 to 42
n52: 53 increased by 2 to 55
n27: 30 increased by 3 to 33
n39: 42 increased by 3 to 45
n52: 55 increased by 3 to 58
n27: 33 increased by 4 to 37
n39: 45 increased by 4 to 49
n52: 58 increased by 4 to 62
n27: 37 increased by 5 to 42
n39: 49 increased by 5 to 54
n52: 62 increased by 5 to 67
n27: 42 increased by 6 to 48
n39: 54 increased by 6 to 60
n52: 67 increased by 6 to 73
n27: 48 increased by 7 to 55
n39: 60 increased by 7 to 67
n52: 73 increased by 7 to 80
n27: 55 increased by 8 to 63
n39: 67 increased by 8 to 75
n52: 80 increased by 8 to 88
n27: 63 increased by 9 to 72
n39: 75 increased by 9 to 84
n52: 88 increased by 9 to 97

I think I’m fairly calm and a lot less confused now…

(Before you say anything, yes I am aware that the code’s snazzed up a bit – it wasn’t the most readable at first, especially when there’s a massive chunk of it…)

Advertisements

One Response to “ConfusedEventHandler += new ConfusedEventHandler(Me.Confused);”

  1. […] « ConfusedEventHandler += new ConfusedEventHandler(Me.Confused); […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: