Planning the Spontaneous

It's more than just a blueprint.

Posts Tagged ‘Publish’

ConfusedEventHandler += (s, e) => ConfusedEventHandler(Me.Extend(s, e));

Posted by Robert Chow on 21/01/2010

So I’ve just been informed that there are a couple more additions to event handling in .NET.

Before notifying an event handler of any new events, you MUST always check to see if it is null.  If it is, then don’t send any events – apparently you get really messed up runtime errors.

Secondly, you can subscribe to an event handler using a lambda method too – it’s quite a pretty neat trick.  As a result, it also allows you to subscribe more than the one method to the event handler.

Here’s the code for the main part of the demo, but rewritten to accomodate the two factors.  I’ve also added in the functionality of one of the subscribers being taken away part way through the program.

public class Program
{
public static event IncreaseNumberEventHandler numberIncreasedEventHandler;

public static IncreaseNumberEventHandler n52Subscribe;

public static void Main(string[] args)
{
public static Number n27 = new Number(27);
public static Number n39 = new Number(39);
public static Number n52 = new Number(52);
numberIncreasedEventHandler += (s, e) => {n27.Increase(s, e); n39.Increase(s, e);};
numberIncreasedEventHandler += (n52Subscribe = (s, e) => n52.Increase(s, e));

Run();
}

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

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
n27: 42 increased by 6 to 48
n39: 54 increased by 6 to 60
n27: 48 increased by 7 to 55
n39: 60 increased by 7 to 67
n27: 55 increased by 8 to 63
n39: 67 increased by 8 to 75
n27: 63 increased by 9 to 72
n39: 75 increased by 9 to 84

Advertisements

Posted in Computing, Placement | Tagged: , , , , , , , , , | Leave a Comment »

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…)

Posted in Computing, Placement | Tagged: , , , , , , , , , | 1 Comment »