Online courses in ASP.NET MVC / Core, jQuery, Angular, and Design Patterns conducted by Bipin Joshi. Read more...
Learn ASP.NET MVC / Core, jQuery, Angular, and Design Patterns through our online training programs. Courses conducted by Bipin Joshi on weekends. Read more details here.

<%@ Page %>

Asynchronous Programming In .NET

Introduction

Support for asynchronous programming is built right into the .NET framework. Asynchronous programming model not only can improve your overall performance but can also make your application more responsive. In this article we will develop a complete example that shows how to develop your components to take advantage of this technique.

About the example

We will develop an example that shows how to write components that have support for asynchronous programming. Note that generally you will also provide a way to make synchronous calls to your components. We will develop a simple component that is supposed to calculate salary of employees. We will first make is to synchronously do its work and then gradually add asynchronous functionality.

Creating the component

If you are using VS.NET then you can start by creating a new component library type of project in C#. If you are not using VS.NET, you can create a .cs file in any text editor and compile it into a library (.DLL). Following code shows the SalaryCalc component
namespace AsyncProgDemo
{
public class SalaryCalc
{
	public SalaryCalc()
	{
	}
	public string Calculate()
	{
	Console.WriteLine("Inside Calculate()...");
	Console.WriteLine("Caclulating salaries...");
	Console.WriteLine("Done...");
	return "ok";
	}
}
}
As you can see this is a very simple code without any actual logic. We have created a namespace called AsyncProgDemo that contains a class called SalaryCalc. The class has one method called Calculate that is supposed to calculate salaries of all the employees of the organization. The method returns string "ok" once done.

Writing Client to consume SalaryCalc component

Let us also write a console client that will consume our component.
using System;

namespace AsyncProgDemo
{
	class Client
	{
		static void Main(string[] args)
		{
			SalaryCalc sc=new SalaryCalc();
			sc.Calculate();
		}

	}
}
The application is straight forward and need no explanation.

Coding guidelines for asynchronous components

Before actually starting with any code let us have a look what guidelines are recommended to design asynchronous components.
  • Provide facility to call method synchronously as well as asynchronously
  • Let the client (caller application) decide which version of the method to be called based on its requirements
  • No code to make the method calls asynchronous should reside in client application. The client should be unaware of how these calls are being handled by your component

Coding guidelines for asynchronous methods

Your asynchronous component should follow certain guidelines for its methods. They are :
  • Write methods for your component that match following signatures:
    • public XXXX()
    • public IAsyncResult BeginXXXX(AsyncCallback ac, Object state)
    • public EndXXXX(IAsyncResult result)
  • In above methods XXXX stands for your method name. For example in our case we will write Calculate, BeginCalculate and EndCalculate methods. The return type of EndXXXX is the same as expected return type of your method (string in our case).
For BeginXXXX methods remember to :
  • Include all IN parameters.
  • Include all OUT parameters.
  • Include all IN/OUT parameters.
  • Accept AsyncCallback and object as the last two parameters.
  • Return IAsyncResult.
For EndXXXX methods remember to :
  • Include all IN/OUT parameters.
  • Include all OUT parameters.
  • Accept IAsyncResult as last parameter.
  • Return the value matching your required data type.
Our method does not involve any parameters but you can have the same way as with any other method.

Namespaces involved

In order to work with our example, you need to import following namespaces in the component:
  • System
  • System.Runtime.Remoting.Messaging

Modified version of SalaryCalc

Let us have a look at new version of SalaryCalc.
using System;
using System.Runtime.Remoting.Messaging;

namespace AsyncProgDemo
{
public class SalaryCalc
{
public delegate string CalcDelegate();

public SalaryCalc()
{
}

public string Calculate()
{
	Console.WriteLine("Inside Calculate()...");
	Console.WriteLine("Caclulating salaries...");
	Console.WriteLine("Done...");
	return "ok";
}

public IAsyncResult BeginCalculate
(AsyncCallback ac,Object state)
{
	CalcDelegate cd=
	new CalcDelegate(this.Calculate);
		
	IAsyncResult result=
	cd.BeginInvoke(ac,state);
	return result;
}

public string EndCalculate(IAsyncResult result)
{
	CalcDelegate cd=(CalcDelegate)
	((AsyncResult)result).AsyncDelegate;
	
	object o=cd.EndInvoke(result);
	return (string)o;
}
}
}
Here, we have added several parts to the original class.
  • We added BeginCalculate method matching signature mentioned above
  • We added EndCalculate method matching signature mentioned above
  • Inside BeginCalculate method we actually call Calculate() method on a separate thread by using a delegate. We started the delegate and return result as object
  • Inside EndCalculate method we similarly ended the delegate. Note that this method will be called by the client after receiving callback from your component. The callback is called automatically for you when Calculate() method ends.

Modified Version of the Client

In order to use asynchronous features of our component we need to modify our client as follows:
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace AsyncProgDemo
{
class Client
{
static void Main(string[] args)
{
	SalaryCalc sc=new SalaryCalc();
	AsyncCallback ac=new AsyncCallback(MyCallback);
	IAsyncResult result=sc.BeginCalculate(ac,sc);
	Thread.Sleep(5000);
}

public static void MyCallback(IAsyncResult result)
{
SalaryCalc sc=(SalaryCalc)result.AsyncState;
object o=sc.EndCalculate(result);
Console.WriteLine("Inside Callback...");
Console.WriteLine("Result of salary Calculation:" + o);
}
}
}
Here, instead of calling Calculate() method directly, we called BeginInvoke passing a callback method (MyCallback). In the callback function we called EndCalculate method and obtained the result. Note that it is the same result that we get when Calculate method is called directly.

Summary

.NET provides support for asynchronous programming from ground up. You can easily develop your components that perform their functions asynchronously. We developed an example that illustrated how to create such components. We also saw guidelines for developing such components.



Bipin Joshi is a software consultant, trainer, author and a yogi having 21+ years of experience in software development. He conducts online courses in ASP.NET MVC / Core, jQuery, AngularJS, and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced Yoga way of life he also teaches Ajapa Meditation to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 31 Aug 2002



Tags : .NET Framework VB.NET C# Components