This article is intended for people who have basic knowledge about delegates in C#.
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
public delegate void MyDelegate(int intValue);
The compiler actually defines a complete class that looks something like this:
class MyDelegate : System.MulticastDelegate
public MyDelegate(Object object, Inptr method);
public virtual void Invoke(Int32 intValue);
public virtual IAsyncResult BeginInvoke(Int32 intValue,
AsyncCallback callback, object object);
public virtual void EndInvoke(IAsyncResult result);
ILdasm.exe displaying the metadata produced by the compiler for the delegate.
The class defined by the compiler has four methods:
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
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:
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.
It is used to identify the method that is to be called back.
This field is usually
null, it can refer to an array of delegates when building a delegate chain.
MyDelegate objStatic = new MyDelegate(Class.StaticMethod);
MyDelegate objInstance = new MyDelegate(new Class().InstanceMethod);
_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
null is passed for the object parameter. Inside the constructor, these two arguments are saved in the
_methodptr private fields, respectively.
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.
MyDelegate objStatic1 = new MyDelegate(Class.StaticMethod1);
MyDelegate objInstance2 = new MyDelegate(new Class().InstanceMethod2);
MyDelegate objChain = null;
objChain = (MyDelegate) Delegate.Combine( objChain, objStatic1);
objChain = (MyDelegate) Delegate.Combine( objChain, objInstance2);
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
delegate void 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.
Below is the sample program for Asynchronous delegate:
public delegate int MyDelegate(int intX);
static void Main(string args)
MyClass objClass = new MyClass();
MyDelegate objDel = new MyDelegate(objClass.MyMethod);
IAsyncResult AsyncRes = objDel.BeginInvoke
(5, new AsyncCallback(MyCallBack), "State info from main thread");
Console.WriteLine("From main thread ");
public static void MyCallBack(IAsyncResult ar)
AsyncResult Result = (AsyncResult)ar;
MyDelegate objDel = (MyDelegate)Result.AsyncDelegate;
int intResult = objDel.EndInvoke(ar);
Console.WriteLine("Output from callback: " + intResult);
string strMessage = (string)ar.AsyncState;
public int MyMethod(int intX)
return (intX * intX);
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.
- 23rd March, 2009: Initial post