Sunday 15 February 2009

The Asynchronous Art of the Dot Net Delegate (BeginInvoke, EndInvoke etc)

Custom Event Handling Techniques Using Delegates (together with event keyword)

Suppose you have a combo box that, on changing state, wishes to send an event to other windows (a kind of internal messaging, if you will). You can define an event handler as a delegate, which takes 2 variables (an object representing the sender, and a custom "event args" object, which encapsulates the state of the event).

Then can explicitly declare the event using the delegate: "public event ClickMeDelegate clickChange" and a method to "fire" the event. All "listeners" register on this event by adding and instantiating new event handler objects.

Declaring, Instantiating and Invoking a Delegate

Note that I DON't say C# delegate, as multicast delegates are found across the .Net framework - e.g. they are also found in Visual Basic .NET and Visual J#. However we will use C# as the lingua franca in which to present delegates.

A delegate in C# is an objectified function pointer. They are .NETiquitous in two ways:

1. EVENT HANDLING
2. ASYNCHRONOUS EXECUTION

To declare a delegate use the following syntax:

public delegate void MyDelegate(string message);

Now MyDelegate becomes a reference type which can encapsulate a named or anonymous method. Now we can define a method "MyDelegateImpl" which matches the signature.

MyDelegate m1 = MyDelegateImpl; // instantiate delegate with NAMED method
MyDelegate m2 = delegate( string msg ) { do s/t; }; // ANONYMOUS method

// invoke
m1("ya"); m2("hoo");

Difference with Multicast Delegates

Maintains an invocation list (implemented as a linked list) of methods it is bound to. The method Combine adds a method to the invocation list and Remove removes it. Combine is used for creating event handlers, that call multiple methods when an event occurs. The binary operators +, - can be used as stand-in for Combine and Remove as this example shows.

It should be strongly emphasised that +,- do not change existing delegates but rather return a delegate representing the result.

Key classes are System.Delegate and System.MulticastDelegate, both part of mscorlib.dll. Multicast delegates can be used to implement the Observer design pattern.

What declaring a multicast delegate entails

When you declare an MCD the CLR creates a class that extends System.MCD, and adds the methods: Invoke, BeginInvoke and EndInvoke. Invoke is what the CLR calls during synchronous execution. To execute asynchronously, use BeginInvoke which is non-blocking and returns an IASyncResult reference. When you call EndInvoke to get the result (this is a blocking call) you need to pass in the reference.

No comments: