Asynchronous Programming Using Delegates

Introduction

Delegates are also used in threading specially for the Callback operation. It enables to call a synchronous method in an asynchronous manner. It is basically used in cases like to report information back after the completion of operation, a thread needs a pointer to be able to execute the Callback, etc.

The relationship between Thread and Delegate is in depth. Thread can't call method so, a function pointer is needed and here Delegate acts as function pointer. Threads can be easily started using Delegate or anonymous method or Lambda expression.

The following is the basic relationship of Delegate with Thread or Task:

Start a Task with Delegate
  1. public void StartThreadWithDelegate()    
  2. {    
  3.     Task task = new Task(delegate { ShowInformation(); });    
  4.     task.Start();    
  5. }    
  6.   
  7. private void ShowInformation()    
  8. {    
  9.     Console.WriteLine("Thread Executed");    
  10. }   
Output

Thread Executed

Thread with Anonymous method

  1. public void ThreadWithAnonymousMethod()    
  2. {    
  3.     new Thread(delegate()    
  4.     {    
  5.         ShowInformation();    
  6.     }).Start();    
  7.     new Thread(delegate()    
  8.     {    
  9.         ShowInformation();    
  10.     }).Start();    
  11. }   
Thread with Lambda Expression
  1. public void ThreadWithLambdaExpression()    
  2. {    
  3.     new Thread(() =>ShowInformation()).Start();    
  4.     new Thread(() =>ShowInformation()).Start();    
  5. }    
Above explanation is the basics related for writing Thread using with Delegate. But, my main motto is to explain the different patterns to implement or execute a part of code asynchronously with the help of Delegate.

The following are the different ways or techniques to execute code asynchronously with the help of Delegate:
  1. Callback 
  2. Polling
  3. EndInvoke
  4. WaitHandler
I will explain above mode of asynchronous execution with the help of Delegate one by one in detail.

Callback

Callback is a way in which a piece or a part of a code is being passed as an argument to other code and expects call back or return back after some time.  Here, Thread starts Async operation but doesn't wait for the completion of operation.
 
Include namespace:
  1. using System.Runtime.Remoting.Messaging;    
The following is the complete code example:
  1. public class CallBackOperation    
  2. {    
  3.     public delegate int MyCallBackOperationDelegate(int number, int numberOfTimes);    
  4.   
  5.     public static int MyMenthod(int number, int numberOfTimes)    
  6.     {    
  7.         for (int counter = 0; counter < 1000; counter++)    
  8.         {    
  9.             number = number + counter;    
  10.         }    
  11.   
  12.         return number;    
  13.     }    
  14.   
  15.     public static void MyCallBackOperation(IAsyncResult asyncResult)    
  16.     {    
  17.         AsyncResult myasyncResult = asyncResult as AsyncResult;    
  18.         MyCallBackOperationDelegate myCallBackOperationDelegate = (MyCallBackOperationDelegate)myasyncResult.AsyncDelegate;    
  19.         var result = myCallBackOperationDelegate.EndInvoke(asyncResult);    
  20.   
  21.         Console.WriteLine("Result : {0}", result);    
  22.     }    
  23.   
  24. }   
  1. static void Main(string[] args)    
  2. {    
  3.     Console.WriteLine("Started Executing Callback Operation...");    
  4.     var myCallBackOperationDelegate = new CallBackOperation.MyCallBackOperationDelegate(CallBackOperation.MyMenthod);    
  5.     Console.WriteLine("After BeginInvoke Operation");    
  6.     IAsyncResult asyncResult = myCallBackOperationDelegate.BeginInvoke(5,10,  CallBackOperation.MyCallBackOperation, myCallBackOperationDelegate);    
  7.     Console.WriteLine("Still Executing");    
  8.     Console.ReadKey();    
  9. }    
Here, my long calculating method has been passed to MyCallBackOperationDelegate Deleage and this method starts executing after doing "BeginInvoke" operation. It doesn't stops another operation. 
 
Output

Started Executing Callback Operation...
After BeginInvoke Operation
Still Executing
Result: 499505  

Polling

Polling is a famous term which means periodically checking for a certain condition. In this technique it continuously asks "Are you still there?" It checks whether Task has been completed or or not. If operation of task is being completed then "EndInvoke" method is being called.
 
The following is the code example:
  1. public class Polling    
  2. {    
  3.     public delegate int MyPollingDelegate(int number, int numberOfTimes);    
  4.     public static int MyCalculation(int number, int numberOfTimes)    
  5.     {    
  6.         for (int i = 0; i < numberOfTimes; i++)    
  7.         {    
  8.             number = number + i;    
  9.         }    
  10.   
  11.         return number;    
  12.     }    
  13.   
  14.     public static void ExecutePollingTechnique()    
  15.     {    
  16.         Console.WriteLine("BeginInvoke Operation Started...");    
  17.         var myPollingDelegate = new MyPollingDelegate(MyCalculation);    
  18.         IAsyncResult asyncResult = myPollingDelegate.BeginInvoke(10, 100, nullnull);    
  19.         Console.WriteLine("After BeginInvoke Operation...");    
  20.   
  21.         while (!asyncResult.IsCompleted)    
  22.         {    
  23.             Console.WriteLine("Still in progress...");    
  24.             Console.WriteLine("I am working other operation...");    
  25.         }    
  26.   
  27.         Console.WriteLine("Asynchronous Programming");    
  28.         long myPollingResult = myPollingDelegate.EndInvoke(asyncResult);    
  29.         Console.WriteLine("Resutl : {0}", myPollingResult);    
  30.     }    
  31.   
  32. }   
Now, execute the method:
  1. static void Main(string[] args)  
  2. {  
  3.      Polling.ExecutePollingTechnique();  
  4.      Console.ReadKey();  
  5. }  
Output

BeginInvoke Operation Started...
After BeginInvoke Operation...
Still in progress...
I am working other operation...
Still in progress...
I am working other operation...
Still in progress...
I am working other operation...
Still in progress...
I am working other operation...
Still in progress...
I am working other operation...
Asynchronous Programming...
Result : 4960  

EndInvoke 

Actually, in this technique generally two methods are being used - BeginInvoke and EndInvoke. It is the basic technique of threading using with Delegate. Method "EndInvokde()" does not return until and unless asynchronous operation completes. 
 
The following is the code example:
  1. public delegate int MyMessageDelegate(int numberOfTimes, int number);  
  2. public  class EndInvoke  
  3. {  
  4.     public static int ShowMessage(int numberOfTimes, int number)  
  5.     {  
  6.         for (int counter = 0; counter <= numberOfTimes; counter++)  
  7.         {  
  8.             number = number + counter;  
  9.         }  
  10.   
  11.         return number;  
  12.     }  
  13.   
  14. }  
Executing Method
  1. static void Main(string[] args)    
  2. {    
  3.     var myMessageDelegate = new MyMessageDelegate(EndInvoke.ShowMessage);    
  4.     Console.WriteLine("BeginInvoke Operation Started...");    
  5.     IAsyncResult asyncResult = myMessageDelegate.BeginInvoke(10, 5, nullnull);    
  6.     Console.WriteLine("After BeginInvoke Operation....");    
  7.     var myMessageResult = myMessageDelegate.EndInvoke(asyncResult);    
  8.     Console.WriteLine("EndInvoke Operation Finished...");    
  9.     Console.WriteLine("Result {0}", myMessageResult);    
  10.     Console.ReadKey();    
  11. }   
Output

BeginInvoke Operation Started...
After BeginInvoke Operation...
EndInvoke Operation Finished..
Result 60 
 
I will explain "WaitHandler" in more detail in the next article. Just read the concept carefully then you will enjoy the real flavor of asynchronous programming using Delegate.

Now, I will discuss about "Delegate.BeginInvoke" method because I have used it everywhere.

People generally use "Thread.Start" method to start thread. But, here we have used "Delegate.BeginInvoke" method with Delegate for the Asynchronous programming. So, I want to explain the differences between both so you will easily understand their purpose.

Thread.Start
 
This method is also being used with Delegate. But, it starts a new O/S thread to execute the Delegate. Here thread is destroyed if Delegate returns value. It is a heavy-weight operation because it performs starting and destroying of thread.
 
Delegate.BeginInvoke:
 
Basically, it calls Delegate on a thread pool. It doesn't destroy the thread on returning the value from Delegate. Here, thread is being returned to the pool so that it will be used by another Task.  So, it doesn't starts the whole process every time. Therefore, it is a light-weight operation. 

Conclusion 

Executing and performing thread using with Delegate is a very good technique.  But, C# 4.0 has provided us a wonderful library named Task Parallel Library (TPL) for the handling of Thread related operations. So, always try to use it. It is very easy and managed.
 
I have attached sample code.
 
Happy coding! 

Next Recommended Readings