Welcome!

.NET Authors: Hovhannes Avoyan, Bruce Armstrong, Pat Romanski, Liz McMillan, Yeshim Deniz

Related Topics: .NET

.NET: Article

Asynchronous Web Services

Don't just call Web services, make them call you back!

Since their conception, Web services have evolved into a core component of software architectures worldwide. The ability to easily distribute processing, allow access via the Internet, and componentize architectures makes Web services a compelling choice for interoperability among systems.

Another convincing argument for the implementation of Web services is the fact that with the current development tools available, they are easy to create and they integrate virtually seamlessly into most systems.

However, the fact that Web services are easy to create, coupled with the reality that .NET essentially walks you through the process of including Web services in a Windows or Web application is, in a way, both a positive as well as a negative. The positive is, obviously, that many developers gain access to the power of Web services with little training or research required. The negative, however, is that many of those developers fail to look deeper into the capabilities of Web services and miss out on some of the richer technology that lies beneath the surface.

One such technology that is often overlooked is the ability to call Web services asynchronously.

The simplest way to call a Web service method is to create an instance of your Web service class and then merely call the method. This may work great in many cases, but it is inherently inefficient. That type of a Web service call is known as a synchronous call, which means that when you call the Web service method, the execution of the calling program is paused (and appears frozen) until the Web service returns with results or times out. At that point, the execution of the calling program picks up where it left off. Asynchronous calls to Web service methods allow you to call the Web service and then continue processing and/or gathering information via a UI while the Web service does its thing.

Because of the real-time nature of Windows applications they are a great place to implement asynchronous calls. If you've ever tried using Web services with a Windows application, you may have abandoned that idea based on the slightly less real-time aspect of Web services (there is a slight delay with each Web service call you make). Asynchronous calls can help alleviate that problem and make Web service calls perform in a much more real-time environment.

For example, let's say you have a search screen in an application which pulls data via a search method from a Web service. With a synchronous call, you'd probably want to have the users enter their search criteria and then hit a button to start the search on the Web service. You'd do this because while the search is running on the Web service, the client application is essentially frozen, waiting for the results.

With an asynchronous call, you could trap the key press in each of the search fields and immediately begin a search on the Web service with the current data in those fields. The user can continue to modify the search criteria while the Web service is churning because the application is not frozen. Each time the user presses a new key, the previous call to the Web service, if it's still running, is cancelled and a new search is called with the new data from the search screen. With this technique, the user will see the search results as he or she is typing - providing a much more real-time feel to your application. In addition, for you usability activists, an extra mouse click has been removed from the search screen because the user no longer has to click a button to begin a search.

So just how does all this happen? It's surprisingly easy to implement. Let's say we have created a Web service that searches a database for users based on some search criteria (for this exercise, we'll just use first and last name). My synchronous call would look something like Listing 1.

While synchronous calls can seem fairly straightforward, asynchronous calls are a bit more complex. There are a number of techniques you can use to make asynchronous calls to Web service methods and each has a certain benefit in different situations. For the situation described here, you'd probably want to use the callback technique. The callback technique of asynchronous Web service calls allows your application to have idle time while the Web service is working. This allows the user to interact with the GUI and, in this case, to refine search criteria.

The callback technique provides a way for your client application to call the Web service method and move on to whatever else it needs to do (or in our case, move into an idle state and let the user keep typing). When the Web service finishes, a callback method in your client application is called where you then can get the results from the Web service call and do whatever processing you need (like fill your list of users that matched the search criterion).

So the first thing to do is define a callback method in the code for your client application (in our case, a Windows application). The method has to have the same signature as the one in Listing 2. Notice the code inside the callback. The IAsyncResult parameter in the method signature contains an AsyncState property which is actually an instance of the Web service that was called. That instance is the one that holds the key to retrieve the results from your Web service method. Cast it to an object of your Web service type and assign it to a variable of that type. Then notice that to get the results of our GetUsers method, you call the method EndGetUsers (remember, the name of our Web service method was GetUsers) while passing it again the IAsyncResult object from the method signature.

You've now implemented the code that will retrieve the results to your Web method call once it has been made. Now all that's left to do is to actually make the call. Notice that when you retrieved the results of the call to GetUsers, you used the EndGetUsers method. Similarly, we'll use a different call to invoke the GetUsers method. We'll use the BeginGetUsers call as outlined in Listing 3.

There are a number of things to notice in Listing 3. First, in the second line of code, we are creating an object of type AsyncCallback. We pass the name of our callback method to the object's constructor. This object will tie our invoked Web service method to our callback method in our client application (defined in Listing 2).

Next, we make the actual call to BeginGetUsers in the third line. Here it's important to note that while the GetUsers method required two parameters (a first name string and a last name string), the BeginGetUsers method requires those as well, but inserts two other parameters in addition to those. The first of the two additional parameters is the object created in the previous line, the callback method object (type AsyncCallback). This lets the Web service know which method to call when it is finished with its work. The second additional parameter is the instance of the Web service. This is the object type to be used in the IAsyncResult object's AsyncState property (see Listing 2) when the Web service results are ready to retrieve. We want that property to hold an object of the type of our Web service, so we pass in the instance of our Web service (MyUsers) here.

More Stories By Aaron Reed

Aaron Reed is an assistant professor specializing in software architecture and design and .NET development at Neumont University in Salt Lake City, UT. He has worked professionally in the industry for over 12 years as a lead architect/designer, development manager, and VP of development. When he isn't spending time reading up on the latest in software development, Aaron loves spending time with his beautiful wife and three children.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.