Audience

This article is intended for people who have basic knowledge about delegates in C#.

Introduction

We all know about the word delegate in the .NET world. But what will the compiler do when seeing the word delegate in your program. The compiler and the CLR do a lot of behind the scenes processing to hide the complexity. I'll focus on how the compiler and the CLR work together to implement delegates. This article will explain to you about the complete class of delegate and the asynchronous processing performed by the delegate.

Using the Code

publicdelegatevoid MyDelegate(int intValue);

The compiler actually defines a complete class that looks something like this:

ILdasm.exe displaying the metadata produced by the compiler for the delegate.

The class defined by the compiler has four methods:

constructor

Invoke method

BeginInvoke method

EndInvoke method

Invoke method is used to call the target method in the same thread. It is a synchronous process. I will explain to you about the BeginInvoke and EndInvoke methods later in this article. Before that, we want to know about how the methods (static and instance) are pointed internally in delegate, probably this is the most significant feature in delegates. There are three non public fields:

_target When a delegate object wraps a static method, this field is null. When the delegate objects wraps the instance method, this field refers to the object.

_methodptr It is used to identify the method that is to be called back.

_invocationlistThis field is usually null, it can refer to an array of delegates when building a delegate chain.

The _target field holds the System.Object type. A reference to the object is passed for the constructor's object parameter, and a special intptr value that identifies the method is passed for the method parameter. For static methods, null is passed for the object parameter. Inside the constructor, these two arguments are saved in the _target and _methodptr private fields, respectively.

Internally, the combine method sees that objChain already refers to a delegate object, so combine will construct a new delegate object. This new delegate object initializes its private _target and _methodptr fields to values that are out of scope here. What is important is that the _invocationlist field is initialized to refer to an array of delegate objects. The first element of the array (index 0) will be initialized to refer to the delegate that wraps the static method. The second element of the array (index 1) will be initialized to refer to the delegate that wraps the Instance method.

Asynchronous Delegates

Delegates can call the methods in an asynchronous manner. If the BeginInvoke method is called, then the CLR will queue the request and return immediately to the main thread. The target method will be called on a thread from the thread pool. The main thread can perform parallel execution to the target method. BeginInvoke method has three parameters:

Input parameter

AsyncCallBack delegate instance

Async State information

objDel.BeginInvoke(5,new AsyncCallback(MyCallback),"Result From Main Program");

The last two parameters are used to provide a callback mechanism that will be invoked when the target method completes. This is called AsyncCallBack delegate.

delegatevoid AsyncCallback( IAsyncResult ar );

If the callback was not specified in the BeginInvoke then the EndInvoke is used in the original thread. It is used to obtain the return value for the asynchronous processing. If the callback was present, then the EndInvoke is placed in the callback method.

Output

Conclusion

Delegate is an object which refers to methods. It can be used in asynchronous or synchronous processes by running the methods in another threads. The asynchronous process is mainly useful for background processing like mailing, database transaction, etc. so the user may not wait until the operation completes.