Home > Articles > Web Services

  • Print
  • + Share This
From the author of

Invoking a Web Service Asynchronously

We assume that the amount of airport information will take a few seconds to compile, which is plenty of time to do some other work. Hence, we can use the signature of the proxy methods as a starting point to figure out how to call the Web Service asynchronously.

Invoking the Web Service

The signature of BeginGetAirports in Listing 3 indicates that you need to pass a string representing the state search string, followed by an AsyncCallback delegate and an object that can represent any information you want to send to the Begin method. You'll get back an object that implements System.IAsyncResult immediately from the Begin method. This object is used to synchronize the callback method with a specific asynchronous call. Listing 4 assumes that a web reference has been made to our Web Service and shows the code for the asynchronous call.

Listing 4—Invoking a Web Service Asynchronously

localhost.Service1 service = new localhost.Service1();
private void button1_Click(object sender, System.EventArgs e)
 IAsyncResult result = service.BeginGetAirports(
 textBox1.Text, new AsyncCallback(Callback), null );

delegate void MyDelegate(IList list, Type type);

private void Callback(IAsyncResult result)
 localhost.Airport[] airports = service.EndGetAirports(result);

 if( InvokeRequired )
  Invoke(new MyDelegate(CreateUserInterface),
   new Object[]{ airports, typeof(Airport)});

The first statement creates an instance of the Web Service class, named Service1. The button1_Click method performs the asynchronous call, catching the return result, passing the state argument from a text box, creating an instant of the callback, and null for the third argument.

The argument new AsynchCallback(Callback) shows you how to construct an instance of a delegate object—a callback. If you check the help, you'll see that the signature of the method named Callback matches that of an AsyncCallback delegate.

Waiting for the Return Value

The delegate method Callback will be called when the Web Service needs to talk to our application. Assuming that everything works correctly in the Web Service, the data should be ready when Callback is called by the Web Service.


The CodeDOM in .NET is used by WSDL.exe to generate the proxy class. The CodeDOM is a great place to explore if you're interested in writing code generators.

The statement in Listing 4 that contains EndGetAirports passes the IAsyncResult the Web Service sent to us, and we send that back to the Web Service to ensure that we're talking to the correct thread in the service. EndGetAirports returns our array of proxy Airport objects defined in the Reference.cs generated file.

The final code beginning with if( InvokeRequired ) is used to manage interaction with the Windows Forms application representing the client. The Web Service Callback is not on the same thread that the form is on, so we can't interact with the Windows Forms controls directly. To display the list of airports on the form, I used another delegate to invoke CreateUserInterface, which dynamically generates form controls based on the type of the object passed. (Due to space constraints this code isn't shown here, but can be found in my C# book and on my web site at www.softconcepts.com.)


To view the threads working in the sample application, place a breakpoint on the callback method in the client and select Debug, Windows, Threads.

There are several options that you can use while waiting for data to return from an asynchronous call. You can call the EndInvoke proxy, which will block until the data is ready, or you can use a WaitHandle object that you can obtain from the IAsyncResult object returned by the BeginInvoke proxy. The WaitHandle class provides you with three ways to block.

And, of course, the benefit is that you can perform useful work while you're waiting on the asynchronous Web Service call to return. Remember, the BeginInvoke proxy returns immediately, so you can add work in the form of code right after the BeginInvoke proxy is called.

  • + Share This
  • 🔖 Save To Your Account