How to Call Web Service Methods Asynchronously From an ASP.NET Page Using the Event-Driven Method in ASP.NET 2.0 and Higher

If you wanted to call a web service method asynchronously from an ASP.NET page in ASP.NET 1.x, you had two options: you could either use thread-blocking, or a callback method. With thread-blocking, you had to be mindful of the affect on other threads, and if you were using a callback method, you had to take steps to make sure that the page load didn't complete before the callback method was executed. In ASP.NET 2.0 and above, however, you have another option, which uses an event to signal that the asynchronous call has completed. It's easy, and even better, the page load won't complete until the event occurs. Here's how to use this convenient functionality.

First, add the Async attribute to the Page directive that will be making the web service call, and set it's value to true, as shown below. This will allow the page to process asynchronously.

<%@ Page Language="C#" Async="true" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

Next, add your web service reference using the WSDL tool in Visual Studio by right-clicking on the website root and selecting Add Web Reference. Then, create an instance of your web service proxy class. For each of your web methods, the class will contain a Completed event. The proxy class generator creates this automatically for you (even if your page doesn't have the Async="true" attribute). Add an event handler to the class of the appropriate delegate type -- the method you specify will be called when the asynchronous call completes. Check out the code below:

protected void btnWebServerAsynch_Click(object sender, EventArgs e)

    TestWebService.Service1 service = new TestWebService.Service1();
    service.WasteSomeTimeCompleted += new TestWebService.WasteSomeTimeCompletedEventHandler(service_WasteSomeTimeCompleted);
    lblWebServiceResponse.Text = "At " + DateTime.Now + ", waiting for web service";


As you can see in the example above, we're creating an instance of our web service proxy class (TestWebService.Service1) and assigning an event handler to the WasteSomeTimeCompleted event which will occur when the WasteSomeTimeAsync() method completes. Speaking of which, this method is also created automatically by the proxy class generator when you add a web reference using the WSDL tool in Visual Studio. In the example above, my web service has a web method named WasteSomeTime(), but the proxy class generator automatically creates an asynchronous version named WasteSomeTimeAsync(). You don't need to do anything extra for this to occur. So, for example, if you had a web service with a method named CalcTaxRates(), when you added the web reference using the Add Web Reference option in Visual Studio, not only would your proxy class contain the CalcTaxRates() method, but also a CalcTaxRatesAsync() method. Obviously, the method with Async appended to the end of the method name is the asynchronous version. In our example above, we're calling our asynchronous version of the method, and then doing a Response.Write() to illustrate the fact that the thread continues after the asynchronous method is called.

Now let's move on to the event handler. The event provides two parameters: the sender object, and an EventParams object. Check out the event handler for my earlier example code:

void service_WasteSomeTimeCompleted(object sender, TestWebService.WasteSomeTimeCompletedEventArgs e)
    lblWebServiceResponse.Text += " " + e.Result;

The EventArgs object has a Result property, which represents the return value of the method (if applicable). Better yet, it's correctly typed -- if your web service's method returns a DataSet, then the Result property will be a DataSet. In my example above, e.Result is a string. When the method has completed, the event is fired and the results represented in the EventArgs' Result property.

It's just that simple. With those few, easy steps, you can call web service methods asynchronously from your ASP.NET pages in ASP.NET 2.0 and above.


PokerDIY said…
Great post (info on where the Beginxxx/Endxxx methods went to is hard to find!)

I have a problem through - I am using a UserControl and not a Page class (ie. no aspx page) so I cannot set the Async="true" setting and I get the following error:

InnerException: Asynchronous operations are not allowed in this context. Page starting an asynchronous operation has to have the Async attribute set to true and an asynchronous operation can only be started on a page prior to PreRenderComplete event.

How can I make this call from a user control? Much appreciated...

Popular posts from this blog

A Generic Method Using HttpClient to Make a Synchronous Get Request

The Cause and Solution for the "System.Runtime.Serialization.InvalidDataContractException: Type 'System.Threading.Tasks.Task`1[YourTypeHere]' cannot be serialized." Exception

How To Mock Out Child Components In Unit Tests of Angular 2 Code