Asynchronous Programming In .NET

Introduction

 
Nowadays, applications often include heavy processing like scientific calculations, backing up or restoring databases, multi-level cross tab reporting, summarizing data, file or directory search, and so forth. While performing such operations, the CPU can get fully occupied in the task, thus making the user interface unresponsive. Consider a case where a method is written to populate the items of a list box using a long-running loop.
 
Source Code 1 shows the code for this task:
  1. private void ExecuteTask() {  
  2.     for (long i = 1; i < 100000000000; i++) {  
  3.         lstCustomers.items.Add(i.ToString());  
  4.     }  
  5. }  
Source Code 2 invokes the method in source code 1 on the click event of btnStart control
  1. private void btnStart_Click(object sender, EventArgs e) {  
  2.     ExecuteTask();  
  3.     MessageBox.show(“Finished”);  
  4. }  
Upon execution of this application, the system might take a long time to process the information to be displayed in the list box. In such a case, it is necessary to inform the user about the status of the application. Also, it may be more sensible to assign this task to the background, while keeping the user interface responsive and continuing to run other tasks in the foreground.
 

Asynchronous Programming

 
Asynchronous programming is a concept where time-consuming applications run in the background while other tasks are performed simultaneously. However, even if an operation is performed in the background, the user needs to be informed of the status. A recommended method would be to use a label or a text box or a status bar showing the status of the process to the user.
 
An example for such a scenario would be a file or a directory search operation where a text box or a label control can be used to show the current status of the search operation. Another example would be CD-burning software. Various chat applications like Yahoo or MSN Messenger make use of the status bar to let the user know the status of an operation. The progress bar control can also show the progress of an operation which takes a long time for execution. Such systems that respond to user inputs while carrying on simultaneous background operations are also called interactive systems.
 
Asynchronous programming uses only one thread and still allows background tasks to take place. They also follow a linear pattern of execution and keep the user interface responsive.
 
Although asynchronous programming uses only one thread and still allows background tasks to take place. They also follow a linear pattern of execution and keep the user interface responsive.
 
Although asynchronous programming offers several benefits to developers It must not be used randomly. It can affect the performance of applications if used unnecessarily.
 

Asynchronous Programming using Delegates

 
Developers commonly use delegates to invoke the asynchronous method in .NET. The signature of a delegate should always match the signature of the method. For example, if there is a method called LongTask() that takes an int as a parameter and returns an integer, a delegate should be defined as shown in the code below.
  1. public delegate int LongTaskDelegate(int time, ref int refParam);  
When a delegate is defined, the common language runtime(CLR) automatically defines BeginInvoke() and EndInvoke() methods on that delegate, which can be called to execute the referenced methods asynchronously.
 
The BeginInvoke() method initiates the asynchronous operation and returns immediately, returning a reference to an object that implements the IAsyncResult interface. The application accesses the interface in order to monitor the progress of the asynchronous operation. Upon completion of the program, the EndInvoke() method is invoked to obtain the result.
 
Four ways to use BeginInvoke() and EndInvoke() to make asynchronous calls. The BeginInvoke() method is used to initiate the call.
 
After the initiation, the following tasks are performed:
  • Do some work and then call EndInvoke(). If the asynchronous operation is not finished, EndInvoke() will block until it completes.
  • Using a WaitHandle obtained from the interface IAsyncResult. AsyncWaitHandle, call the WaitOne() method to block until the operation completes. Then call EndInvoke().
  • Poll the returned IAsynResult.IsCompleted property to determine when the asynchronous operation has completed. Then call EndInvoke().
  • Pass a delegate for a callback function that you supply (of type IAsyncCallback) to BeginInvoke(). When the asynchronous operation completes, that callback function will be executes. Code in the callback function calls EndInvoke().
Source Code
  1. private void btnStart_Click(object sender, EventArgs e) {  
  2.         LongTaskDelegate objLongDeleg = new LongTaskDelegate(LongOperation);  
  3.         int refParam = 0;  
  4.         //call BeginInvoke to initialize the asynchronous operation   
  5.         IAsyncResult ar = objLongDeleg.BeginInvoke(5000, ref refParam, null, null_;  
  6.             //Poll for completion  
  7.             while (!ar.IsCompleted) {  
  8.                 MessageBox.show(“Waiting  
  9.                     for completion”);  
  10.                 System.Threading.Thread.Sleep(1000);  
  11.             }  
  12.             //Call EndInvoke to harvest the Result  
  13.             int longResult = objLongDeleg.EndInvoke(ref refParam, ar); txtResult.Text = ”Result = ”+longResult.ToString() + “\r” + “Reference Parameter” + refParam.ToString();  
  14.         }  
  15.         public int LongOperation(int time, ref int refParam) {  
  16.             //Simulate a long running operation  
  17.             while (time > 0) {  
  18.                 System.Threading.Thread.Sleep(1000);  
  19.                 Time -= 1000;  
  20.             }  
  21.             refParam = .56;  
  22.             return 1;  
  23.         }  
In this source code, the program makes an asynchronous call to a method that starts a long operation. The program simply goes into a wait loop, displaying the message until the specified second is elapsed. The return values are then set including a ref parameter. The application performs other tasks while waiting for the asynchronous call to complete.
 

IASyncResult Interface

 
The IASyncResult interface represents the status of an asynchronous operation. It has four important properties, listed below:
  • AsyncState: Returns a user-defined object that contains information regarding an asynchronous operation
  • CompletedSynchronously: Determines whether the asynchronous operation completed synchronously.
  • IsCompleted: Determines whether the operation is completed or not.
  • AsyncWaitHandle: Returns a WaitHandle object that is used to wait for the operation to complete.

Summary

 
Asynchronous programming is used when time-consuming can result in unresponsive user interfaces. Delegates are often used to invoke asynchronous methods in .NET. Every delegate implicitly defines a BeginInvoke() and an EndInvoke() method. The IAsyncResult interface represents the status of an asynchronous operation.