(Download the project files for this tip.)
The old computer adage: "A system is only as fast as its slowest component" is no more accurate than when working with Web services. If your application calls a Web service, especially a Web service that resides outside your corporation's environment accessible over the public Internet, you must take into account that you can't accurately predict on a consistent basis how long it will take to return the result back to your client application. If you call a Web service in a "synchronous" fashion (the default way), your application will be blocked from processing until the resulting message is returned or the call to the Web service times out. This could require your users to wait an extraordinarily long time before they can continue to use your application.
In the case of a Win Form application, this means that the application will prevent the users from clicking or otherwise interacting with your application. In the case of a Web Form application, this means that users of your site will have to wait for a page to be completely rendered before they can see anything in their browser. Obviously, this must be taken into consideration before developing your client application with a mind to optimize how you call the Web services.
In this tip, I'll explain how to call Web services asynchronously from Win Forms. In the next, I'll demonstrate how to call Web Services asynchronously from ASP.NET Web Forms. The approach you take will be dramatically different because for Win Forms we'll use a Callback approach, and for Web Forms we'll use a WaitHandle object approach (which I'll discuss in depth next time).
Basically, when calling Web services from a Web Form, we'll use a "callback" technique. This allows us to make a call to a Web service then return control of the application back to the user. The callback technique is enabled as we create a Web Reference in Visual Studio.NET. The proxy that is automatically generated will contain a Begin<WebMethodName> function (substitute the <WebMethodName> with the name of the function that you are calling). To use this, we'll simply create a function whose sole purpose is to handle whatever is returned from the Web Service. Then, when we want to perform the call to the Web service in our code, we send a reference to the callback function we created to the Begin<WebMethodName> function. When the result is returned from the Web service, the End<WebMethodName> function in the proxy is invoked where the callback function is called. The application can be refreshed with new information that was retrieved from the Web service with minimal disruption to the user's interaction with the application.
One point of clarification: calling Web services asynchronously from your .NET application, whether it is a Web Form, Win Form, another Web service or other .NET type application, does not require the provider of the Web service to do anything special at all. The provider can use .NET Web services, or any other programming language and platform to create the Web Service. In other words, asynchronous calls have nothing to do with the provider and everything to do with the client.
In the following C# snippet, I will call a Web service called GetCustomerSalesInformation from my Win Forms application. When the user clicks Button1, a call will be made to the BeginGetCustomerSalesInformation function generated by the proxy. A function I create called HandleCallback will actually update the Win Form with customer sales information.
private void button1_Click(object sender, System.EventArgs e)
localhost.CustomerSales wsCustomerSales =
AsyncCallback cb = new AsyncCallback(HandleCallback);
public void HandleCallback(IAsyncResult ar)
localhost.CustomerSales wsCustomerSales =
I've provided the source code for the entire example for you to download and try for yourself. The example allows you to click the first button (button1) which calls the Web service. You can then click a second button (button2) repeatedly to append the letter "A" into the second text box. I did this to illustrate how the user is not prevented from continuing to interact with the application while waiting for results from the Web service. When the Web service is finished, it will populate the textBox1 with the result without disrupting the user's interaction with the application.
Tune in next time for a tip on calling Web services asynchronously from Web Forms using the WaitHandle object instead of callbacks.
About the Author
Robert Tabor is a Microsoft Certified Professional in Visual Basic with over six years of experience developing n-tier Microsoft-centric applications for some of the world's most prestigious companies and consulting organizations, such as Ernst & Young, KPMG, Cambridge Technology Partners, Sprint, American Heart Association, and the Mary Kay Corporation. Bob is the author of Microsoft .NET XML Web Services by Sams Publishing, and contributes to SoapWebServices.com and LearnVisualStudio.NET. He is currently working on initiatives within Mary Kay, the second largest eCommerce site in retail volume on the net, of how to utilize .NET within their e-business group.