7/8/12

Asynchronous programming in .NET - Part 1

Asynchronous programming in .NET is facilitated via Delegates. A delegate is a mechanism that is used to delegate a method call as shown in the code below.



//my custom class in the class library where i have defined the delegate
public class MyCustomDelegates
{
 public delegate string MyFootballDelegate(string team);
}

public class Client
{
 public void ProcessDelegates()
 {
   MyFootballDelegate objDelegate = Dallas;
   objDelegate("cowboys");
 }
 
 private string Dallas(string team)
 {
  //do something here
  return string.format("{0} - {1}","Dallas", team);
 }
}


In the code above, the Client creates an instance of the Delegate called MyFootballDelegate and assigns a method Dallas to it. The Client then invokes the delegate passing in an input value called "cowboys".So what the client is doing is delegating the act of calling that method Dallas to an instance of the MyFootballDelegate class(the compiler internally converts a delegate declaration into a class).

BeginInvoke() and EndInvoke()

In the code above the Client blocks until the method Dallas completes, so this use of delegates is not really asynchronous. To make the call asynchronous the Client needs to invoke BeginInvoke and EndInvoke methods on the delegate as follows:


public class Client
{
 public void ProcessDelegates()
 {
   MyFootballDelegate objDelegate = Dallas;
   iAsyncResult objAsyncresult = objDelegate.BeginInvoke("cowboys",null,null);
   string result = objDelegate.EndInvoke(objAsyncresult);
 }
 
 private string Dallas(string team)
 {
    //do something here
           return string.format("{0} - {1}","Dallas", team);
 }
}


The call to BeginInvoke uses a thread from the .NET Thread pool and queues up the delegate call. So it blocks the calling code for only a brief moment.The Client then calls the EndInvoke to get the result from the method call.

Completion Callback Methods

The Client, instead of calling EndInvoke explicitly, can pass a callback method to the BeginInvoke method that is invoked as soon as the method Dallas ends. Code is as follows:

public class Client
{
       public void ProcessDelegates()
       {
   MyFootballDelegate del= Dallas;
          iAsyncResult obj = del.BeginInvoke("cowboys",DallasCallback,null);   
 }
 
 private string Dallas(string team)
 {
          //do something here
          return string.format("{0} - {1}","Dallas", team);
        }
 
 //the callback method must have the following signature
 private void DallasCallback(IAsyncResult result)
 {
  //call to EndInvoke happens here and the result is obtained here
 }
}


NOTE:
In the code above, the Client specifies the method DallasCallback as the callback in the BeginInvoke call.So the thread from the thread pool that executes the Method Dallas,will also call the callback method as soon as the Dallas method completes. So the code in the DallasCallback method needs to be thread-safe.Besides, a certain amount of thread synchronization will be necessary to handle the interaction between the calling code and the delegate call/callback methods related code

The code in the callback method needs to call EndInvoke on the delegate as follows:


private void DallasCallback(IAsyncResult result)
{
 //call to EndInvoke happens here
 AsyncResult objreturn = (AsyncResult)result;
 MyFootballDelegate objDelegate = (MyFootballDelegate)objreturn.AsyncDelegate;

        //the value returned by method Dallas
 string result = objDelegate.EndInvoke(result); 
}

No comments: