by April 3, 2003 0 comments

In this part of our .NET Developer Series, we focus on some advanced concepts of ASP.NET. We’ll see how to communicate asynchronously with ASP.NET-based Web services. With little or no modifications, the concept can be applied to asynchronous invocation of other non-ASP.NET Web services also.

As usual, we’ll use code to visualize and understand concepts. Here, we have a Web service that shall return a count of number of prime numbers found till a specified number. For example, if 10 is passed as the argument, then the Web service shall return 4 since there are four prime numbers till 10, namely 2,3,5 and 7. You will find the complete Web service source code on this month’s PCQuest CD as Code 1 in

The Web service exposes just one method, Prime, that takes an integer as an input and counts the number of prime numbers till the specified number. Once that is done, the count is returned to the caller. The logic for counting primes and checking a number for primesness is relatively straightforward. 

We installed this Web service in a virtual folder, wstester, on my local machine, and can call it using a browser as http://localhost/wstester/wstester.asmx, where wstester.asmx is the Web service source file. Next, we create its proxy using the WSDL utility that comes with the .NET SDK installation, as follows: 

wsdl /l:cs http://localhost/wstester/wstester.asmx 

This produces the wsprime.cs file. The /l parameter is used to specify the language in which the proxy source code will be written, and cs specified the use of C#.

Inside WSPrime.cs 
If you open up the proxy file that was created, you will find that it looks like what is given as Code 2 (in Code.rtf on CD). The constructor initializes the URL property to point to the location of the Web service. However, the focus of our attention are the three versions of the Prime method: 

  • The first version, with the name Prime, is a synchronous call to the actual Web service method, and shall block until the Web service returns. 
  • The second version is the asynchronous one, and is comprised of the Begin Prime
    and EndPrime methods. 

Actually, for each exposed method in a Web service, the WSDL utility creates these two versions of the method. The asynchronous version is comprised of two methods each, with Begin and End prefixed to the method name. Usually, developers overlook the asynchronous version of the method, and use the synchronous one, after instantiating the Web service proxy class. Using the asynchronous version requires a little more effort by the developer, but can release the caller from getting blocked when the Web service method is called. Once the call is placed using the Begin method of the proxy, the Begin method sends the request to the Web service and then immediately returns to the caller, which lets the caller do any other work. Once the Web service method is done with its work, it calls back the caller of the Begin method. 

So, the question that will be in your mind now is, “How will the Web service notify the caller?” Well, if you check carefully in the example proxy source code (in Code 2 on CD) , the
Begin Prime method takes three parameters instead of one, which the Web service method actually takes. The second-last parameter,
System. Async Callback callback, is a delegate object to which the Web service will notify, and hence callback, when it is done. The last parameter, object
async State, is any state information that you may wish to send to the delegate for its working, when the Web service calls back. 

Now that we have some basics clear, let’s have a look at an implementation of an asynchronous client for the above examplified Web service (see Code 3 on Code.rtf on CD): 

Let’s go through this source code logically, in an application-flow manner. First, the number till which prime numbers have to be counted is taken as an input, and ensured that it is greater than 1. Next, wsp, an object of WSPrime class, is instantiated, which, if you remember from the source code above, is the Web service proxy class. 

Next, since we have to call the Web service method asynchronously, and hence have to use
Begin Prime, we create an AsyncCallback delegate object (hence, we specify using System.Runtime.Remoting.Messaging since this name space contains the AsyncCallback class) and pass it the address of the method to be called back, namely the static PrimeDoneCallback method of the TestProxy class, which is our main application class. The delegate is defined as a static method of the class, but could have been easily changed to an instance method. 

Finally, the Begin Prime method is called on the wsp object and the number, till which prime numbers have to be counted, is passed as the first argument, followed by the callback delegate object acb, and a pointer to the proxy class object. Why have we passed the pointer to the proxy class object? Well, it so happens that whenever we have to call a Web service method asynchronously, we have to do it in pairs of the Begin/End methods. Since the
Begin Prime method is called within Main, and control will return to our callback method when the Web service method has finished its work, we need to have, in the callback method, the proxy class object against which the EndPrime method can be called, and obtain the result of Web service method invocation. Thus, the proxy class object, wsp, is passed as the last parameter to
Begin Prime. 

The Begin Prime method returns immediately, which leaves the caller (that is, Main) to do other tasks. So, in the sample client above, we have programmed Main to calculate the number of prime numbers till the number specified by the user. Of course, you can do anything here, but we did this so that the output could show results for comparison. Once the work is done,the output is shown to the user, and the application is made to block on a static variable of our application class so that our application doesn’t exits before the Web service sends the callback. 

When the Web service sends the callback, Prime Done Callback method is called. This method receives only one argument, which is of the type
IAsync Result. We extract the object pointer to the proxy class object, that was sent as an argument to the
Begin Prime method call, from the Async State property, and appropriately box it. This is followed by the call to EndPrime method on the proxy class object, passing it the
IAsync Result argument that the delegate method received. The EndPrime method returns the result of the Web service call, which is then displayed as the output, and the flag variable, bEnd is set to true so that the Main method, which is blocked on the flag, gets released and the application can exit. 
Compile proxy-source code

To compile the proxy source code, execute the following command at the VS.NET command prompt.

csc /t:library wsprime.cs 
Next, compile the Web service client by referencing the Web service proxy assembly, as shown below. 

csc /r:wsprime.dll wsprime_client.cs 
As evident from above, with a little more effort, a developer can reap the benefits of asynchronous callbacks in Web services, and can make applications more responsive and scalable. Surprisingly, a good amount of development community doesn’t take advantage of this fact, rendering asynchronous Web service communication under-utilized. 

Kumar Gaurav Khanna,  a Microsoft .NET MVP runs

No Comments so far

Jump into a conversation

No Comments Yet!

You can be the one to start a conversation.