Improve Your Technology

Just another blog for techology

Invoking Methods Asynchronously using Delegates

Invoking Methods Asynchronously using Delegates

Introduction

Asynchronous operation improves the program responsiveness and availability. In my past article titled Asynchronous Programming In .NET , I explained how to design your components with built-in support for asynchronous operations. But what if some one has already developed the component and that too without asynchronous programming support? In such cases delegates can come to the rescue. In fact that is the topic of this article.

Delegates and asynchronous operations

Delegates provide a built-in way to call a method asynchronously. Whenever you create an instance of the delegate, it automatically provides you with two methods.

  • BeginInvoke(parameter list, AsyncCallback callback, object state)
  • EndInvoke(IAsyncResult result)

Using the BeginInvoke method you call the method under consideration. When the method finishes, .NET calls the supplied callback function inside which you are  supposed to call the EndInvoke method. Behind the scene these methods use threads  from the .NET ThreadPool.

BeginInvoke method

The BeginInvoke method accepts all the parameters as per the method signature. For example, if your delegate signature is:

public delegate int AddNumbersDelegate(int x,int y);

then BeginInvoke will accept x and y as first two parameters.

Next comes the AsyncCallback instance. This is another delegate that points to the callback function that will be called when the method completes. The callback function mentioned above must have following signature:

public void MyCallback(IAsyncResult result)

Finally, you can pass some state information to the method via state parameter. This is useful in case you want to pass some information other than method parameters.

EndInvoke method

The EndInvoke method takes only one parameter that is of type IAsyncResult. At runtime this parameter provides information about the state information being passed, delegate that is invoking the method etc. Also, the EndInvoke method gives you the return value of the method being invoked.

Example

Let’s see how it works with an example. The example consists of three classes – Class1, Class2 and Class3. Class1 is the class that contains Main() and is used to actually invoke the method in asynchronous manner. Class2 is the class that contains a method (Add()) that we want to call asynchronously. Class3 contains a method (MyCallback()) that will be supplied as a callback to the BeginInvoke() method.

using System;

using System.Runtime.Remoting.Messaging;

namespace AsyncViaDelegates

{

public delegate int AddNumbersDelegate(int x,int y);

class Class1

{

[STAThread]

static void Main(string[] args)

{

                Class2 c2=new Class2();

                Class3 c3=new Class3();

                AsyncCallback callback=new AsyncCallback(c3.MyCallback);

                int state=100;

                AddNumbersDelegate d=new AddNumbersDelegate(c2.Add);

                d.BeginInvoke( 10,20,callback,state);

                System.Threading.Thread.Sleep(3000);

}

}

 

class Class2

{

                public int Add(int a,int b)

                {

                                return a+b;

                }

}

 

class Class3

{

                public void MyCallback(IAsyncResult result)

                {

                                AsyncResult ar=(AsyncResult)result;

                                AddNumbersDelegate d=

                                (AddNumbersDelegate)ar.AsyncDelegate;

                                int state=(int)ar.AsyncState;

                                int i=d.EndInvoke(result);

                                Console.WriteLine(i);

                                Console.WriteLine(state);

                                Console.ReadLine();

                }

}

}

  • We begin by importing two namespaces. The second one is important as it contains AsyncResult class used later in the code.
  • We declared a delegate called AddNumbersDelegate that accepts two integers and returns an integer
  • The class Class2 is the class that actually contains the function that we want to call asynchronously. In our example this function is Add()
  • Note that since we want to call this function via the delegate our delegate signature matches with the signature of Add.
  • The function simply accepts two integer parameters and returns sum of those parameters
  • We also have Class3 that contains the definition of the callback function (MyCallback)
  • In the Main() method we created the instances of Class2 and Class3
  • Then we created an instance of AsyncCallback delegate by passing reference to the MyCallback method. This instance will passed to the BeginInvoke() method later
  • We then declared an integer variable called state. This variable do not take part in any processing. We are using it just to illustrate how to pass the state information to the delegates
  • Next, we created the instance of AddNumbersDelegate delegate called d and pass the reference of Add() method to it.
  • Normally i.e. in synchronous mode you would have invoked this delegate as d(10,20) but here we want to invoke the Add() method asynchronously and hence we used the BeginInvoke() method of the delegate.
  • As explained earlier, the BeginInvoke method accepts all the parameters of the actual method (Add) followed by a callback function and state information.
  • We then halt the program execution for 3 seconds so that the callback function (MyCallback) will be called. In real life situation you can perform some other processing instead.
  • The callback function receives an instance of a class that implements IAsyncResult interface. .NET framework contains one such class called AsyncResult. In fact instance of this class is what you receive in the callback function.
  • The AsyncResult class contains a property called AsyncDelegate that gives the reference to the delegate on which you called BeginInvoke() method. It also provides the state information passed while calling BeginInvoke() through the AsyncState property.
  • Using the delegate reference mentioned above we called EndInvoke() method on the delegate. The return value of Add() is obtained via this call to EndInvoke() method.
  • Finally, we simply print the results on the console.

Summary

.NET provides native support for asynchronous operations. This article explained how to invoke methods asynchronously using delegates. This method is useful when the component developer has not provided asynchronous support for the component but you still want to call the methods asynchronously. The disadvantage of this method, however, is that you need to define your own delegate.

Advertisements

July 31, 2008 - Posted by | Delegates | ,

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: