AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=337&pId=-1
Review of Making Web Service Calls
page
by Wenfeng Gao
Feedback
Average Rating: 
Views (Total / Last 10 Days): 78541/ 147

Introduction

Web services allow programs written in different languages on different platforms to communicate with each other in a standards-based way. Web services play a key part in the service oriented architecture and help on scaling applications. More and more applications use Web services.

 

Web services are slow due to the latency involved when making calls across a network. Applications consuming Web service calls face performance issues. For examples, Microsoft® Windows® Forms applications, for instance, may appear frozen while they wait for a call to a Web service to return. If you are calling a Web service from a Microsoft® ASP.NET page, you may find that multiple Web service calls make your page display many times slower. If you have an application that is making many Web service calls, then it's important to think about how to call them as efficiently as possible.

 

In this article, I will review the various options provided by the Microsoft .NET Framework for making Web service calls and focus on addressing performance issues when making Web service calls. I will focus on three kinds of clients consuming Web services: Windows Forms clients, ASPX pages, Web services.

 

You can find most materials in this article in Matt Powell’s excellent articles [1], [2], [3].

Making Web Service Calls from Windows Forms Clients

In this section, I’ll walks through the various options provided by the Microsoft .NET Framework for making Web service calls and discuss the best way to consume Web services from Windows Forms clients.

 

Most materials in this section are adapted materials from [1] and [5]. See [1], [5], [8], [9], and [18] in more details.

 

In this article, I’ll use a Web method created in Matt’s articles that purposefully could take a long time to return. The Web method is called DelayedResponse and takes an integer as its only parameter and returns a string.

 

 

When you choose the Add Web Reference option in Microsoft Visual Studio® .NET, Visual Studio .NET generates a proxy class. Web services are called through the proxy class. This technique allows the application developer to call a local method on the proxy class that takes care of the details of generating, transmitting and parsing the XML required to actually calling the remote Web service. The generated proxy class provides three methods for each Web service operation. One method named the same as the Web service operation that calls the Web service synchronously and a pair of methods prefixed with Begin and End to call the Web service asynchronously.

 

Calling the Web service synchronously is now a matter of creating an instance of the proxy and calling the method named the same as the Web service operation:

 

 

A typical communication scenario that a Windows Forms client consumes a Web service is shown below.

 

        

 

A Windows Forms client calls a Web service and the Web service retrieves data from a database. Three components might sit on different machines and the calls made might be lengthy network calls.

 

Web services are slow due to the latency involved when making calls across a network, especially over a relatively low-speed wireless connection. Communicating large amounts of data may also cause the slowness.

 

If you make a lengthy Web service call synchronously, the user interface of your application might freeze. In Windows Forms applications, the user experience we focus on is to allow the applications to do other things while making the Web service calls. As you can see later, the best way to make Web service calls from Windows Forms clients is to make asynchronous Web service calls or combine asynchronous Web service calls with an asynchronous delegate.

 

Before introducing asynchronous Web service calls, I want to show you how to make a synchronous Web service call with an asynchronous delegate.

 

When a managed application is executed, the runtime offers a pool of threads that will be created the first time the code accesses it. The thread pool allows jobs to be run in the background without the overhead of frequently creating and destroying separate threads for each task.

 

There are several ways to use the thread pool. For example, you can use the thread pool method QueueUserWorkItem. The way I’m going to use is to use asynchronous delegates. For more information on using delegates, see [16].

 

 

Here is how it works. We first define a delegate named AsyncDelegate. In the button click event handler, we create an instance of that delegate that refers to the method (named Callback) that will do the work. Then, call BeginInvoke to run the Callback method on a thread from the thread pool. We also pass an AsyncCallback object and the AsyncDelegate object in the BeginInvoke call. Passing the AsyncCallback object will cause the CleanUpDelegate method invoked after the Callback method completes and the AsyncDelegate object will be used to make the EndInvoke call in the CleanUpDelegate method.  In the Callback method, we make a synchronous Web service call. Then, make a Control.Invoke call to deliver the response message from a thread pool thread to the UI thread and update the UI in the UpdateUI method. After the Callback method completes, the CleanUpDelegate method is invoked and we make the EndInvoke call to clean up memory.

 

The Control.Invoke call here is necessary because only the UI thread is allowed to access properties of a control. Unfortunately the Control.Invoke call here does not work in the .NET Compact Framework. The .NET CF supports just one of the overloaded Control.Invoke methods from the full .NET Framework. Control.Invoke takes a single parameter; a delegate specifying which method to execute on the UI thread. The delegate must be of type EventHandler. To pass data, you have to use shared data.

 

Always call EndInvoke after your asynchronous call completes. This will pretend you from the memory leak.

 

Asynchronous delegates are a commonly used approach to send a task from the calling thread to a thread pool thread. While doing the task, the thread pool thread might need to communicate with the UI thread. The best way to do that is to use the message-passing model introduced by Chris Sells and Ian Griffiths (see [6], [7], [8], [9], and [10]).

Making an Asynchronous Web Service Call

As noted earlier, the generated proxy class provides a pair of methods prefixed with Begin and End to call the Web service asynchronously.

 

Before retrieving the results of an Asynchronous Web service call, the application must first determine that the call has completed. An application can choose to be notified of completion, use WaitHandles or can poll to determine if the Web service call has completed.

 

Notification

 

In most cases, notification is the best choice as it allows the application to initiate the call to the Web service and then proceed without any other special handling.

 

 

The application passes an AsyncCallback delegate to the BeginDelayedResponse method. The delegate will automatically be called when the Web service call completes.

 

Note that the call to BeginDelayedResponse does not directly call the Web service but instead queues the actual Web service call then returns immediately. No information from the Web service itself is available when the call returns.

 

Using notifications can be very efficient if you are making a lot of simultaneous Web service calls.

 

The callback function will run on a thread pool thread. So you should use Control.Invoke to send the response to the UI thread. Using notifications is the only option to allow you to release the thread you are currently executing in.

 

Polling

 

In some rare occasions, an application may wish to continue processing while periodically checking on the Web service call.

 

 

Using IAsyncResult.IsCompleted, the application can determine if the Web service call has completed. If EndDelayedResponse is called before the request has completed, it will simply block until the request does complete.

 

One of the problems you need to watch out for when using polling to determine if your call has completed is that you can end up using a lot of your machine's CPU cycles if you are not careful.

 

Using WaitHandles

 

WaitHandles are convenient for scenarios where you need to make asynchronous calls, but you do not want to release the thread you are currently executing in. With WaitHandles you can do some processing after your Web service call has been made and then block until the Web service call has completed.

 

 

When the Web service call completes, the AsyncWaitHandle is signaled. Using the WaitOne method on the AsyncWaitHandle will cause the calling thread (normally the main application thread) to block until the Web service completes.

 

There are also static methods called WaitAll and WaitAny in the WaitHandle class. These two static methods take arrays of WaitHandles as parameters, and either return when all the calls have completed, or as soon as any of the calls have completed, depending on which function you call. WaitAll allows multiple Web service calls to execute at the same time.

 

The WaitOne, WaitAll, and WaitAny methods all have the option of taking a timeout as a parameter. This allows you to control just how long you are willing to wait for a Web service to complete.

Many times, applications will combine WaitHandles with one of the other asynchronous approaches. I’ll show you an example later.

 

6. A synchronous Web service call with an asynchronous delegate vs. an asynchronous Web service call

 

Asynchronous Web service calls are more efficient, especially for an infrequent call or multiple calls. Two approaches are almost the same for a frequent call.

 

The best way to make Web service calls from Windows Forms clients is to make asynchronous Web service calls or combine asynchronous Web service calls with an asynchronous delegate.

 

7. Asynchronous Web service calls with asynchronous delegates

 

Many times, applications will combine asynchronous Web service calls with an asynchronous delegate. For example, you want to generate a report. Report data are from a remote database and a Web service. Both calls might be lengthy calls.

 

 

Using an asynchronous delegate sends the task from the UI thread to a thread pool thread. Using an asynchronous Web service call allows to retrieve data from the database and the Web service simultaneously.

 

Making Web Service Calls from ASPX Pages: Responsiveness of ASP.NET Pages

In this section, I’ll show you how to eliminate performance problems and the devouring of thread-pool resources with asynchronous approaches to Web service calls that uses Microsoft ASP.NET.

 

1. Responsiveness of ASP.NET applications

 

A typical communication scenario is shown below.

    

 

A Web browser sends a request to a Web server. To generate a page, the ASP.NET worker process might need to get data from a remote database through a Web service call. Four components might sit on different machines and the calls made might be lengthy network calls.

 

As we noted earlier, the user experience we focused on Windows Forms applications was to allow the applications to do other things while making the Web service calls. Web Forms applications utilize the request-response model. So the users get used to not expect to do other things (with the application they run) while making a request. However a user will not be happy to see that a page takes 10 seconds to load in cases where heavy loads on the Web site happen while it normally takes 2 seconds to load. So the user experience we focus on Web Forms applications is to provide the (almost) same user experience in cases where heavy loads on the Web site happen, as experience that users normally have.

 

ASP.NET uses the process-wide CLR thread pool to service requests. The default size of the CLR thread pool is 25 in Framework 1.0 and 20 in Framework 1.1, with separate limits for I/O threads and worker threads. In cases where threads from the thread pool are used to perform work that is not CPU-intensive (like making a request to a remote database or invoking a remote Web Service), it is possible to saturate the thread pool without high CPU utilization. In this scenario, the thread pool is in fact the bottleneck.

 

There are two approaches to use the thread pool threads efficiently while making Web service calls:

  • Asynchronous PreRequestHandler Execution
  • Asynchronous Pages

The asynchronous PreRequestHandler execution approach was first introduced by Matt Powell in [3]. The asynchronous pages approach is a combination of [13], [11], [12], and [3]. It utilizes the techniques about asynchronous HttpHandler discussed by Jason Clark and Fritz Onion in [13], [11], and [12], the techniques about asynchronous pages described by Fritz Onion in [11] and [12], the techniques about storing and passing the request-specific state along with the proxy utilized by Matt Powell in [3].

 

Both approaches allow freeing up the thread pool thread that serves the original request to service additional requests. This is the key for the performance gain! For this reason, we have to make asynchronous Web service calls with the notification (callback) approach.

 

Two approaches differ on the start and the end points in the HTTP pipeline and also how many pages the approach serves. I’ll discuss the start and the end points in the HTTP pipeline next.

 

Making Web Service Calls from ASPX Pages: The Start and End Points of the HTTP Pipeline

I will discuss the start and the end points in term of the sequence of some important events that a request (and a response) might pass through. See [12], [14] and [15] for the HTTP pipeline in details.

 

The following diagram lists some important events in the HTTP pipeline. Most are HttpApplication events.

 

 

With the asynchronous PreRequestHandler execution approach, both the start point and the end point are at the stage of the PreRequestHandlerExecute event. The PreRequestHandlerExecute event occurs just before the HttpHandler for the request is called.

 

With the asynchronous page approach, the start point is at the time when an asynchronous handler is created. This happens after the PreRequestHandlerExecute event and before the Page_Load event. The response data from the Web service call will be available on the Page_Load event handler. The end point is after the Page_Load event (actually after the ProcessRequest call) and before the PostRequestHandlerExecute event.
Making Web Service Calls from ASPX Pages: Asynchronous PreRequestHandler Execution

ASP.NET has support for writing event handlers that can be notified at various times during the processing of an Http Request. One such event is the PreRequestHandlerExecute event. There is also asynchronous support for PreRequestHandlerExecute notifications that can be registered for using the AddOnPreRequestHandlerExecuteAsync method of the HttpApplication class. We are going to use the asynchronous PreRequestHandler option to provide an asynchronous execution mode for making our Web service calls.

 

The following are the steps for using the asynchronous PreRequestHandler execution after adding a Web reference:

  1. Creating a class implementing IAsyncResult and a custom proxy class.
  2. Creating a BeginEventHandler method, an EndEventHandler method, and an intermediate MyCallback.
  3. Calling the AddOnPreRequestHandlerExecuteAsync method.
  4. Using the response data.

 

You can find most materials about this approach in Matt Powell’s excellent article [3]. The approach I present here is a slightly simplified version of Matt’s approach. I do not store a proxy and an IAsyncResult interface in a MyAsyncResult object. Instead of getting the response data of the Web service call in the EndEventHandler method, I get it in the MyCallback method.

 

Step 1. Creating a class implementing IAsyncResult and a custom proxy class

 

We provide an implementation of IAsyncResult which is used to store the request-specific state that we need to use during the processing of a request.

 

There are several changes made on the MyAsyncResult stubs for interface System.IAsyncResult, added by Visual Studio .NET by pressing TAB. The first is that we add two member variables: cb will be used to store the callback function passed by ASP.NET and be called when my asynchronous work has completed, and asyncState that holds the state for ASP.NET when it calls me. The second is that we implement the AsyncState property to support both reading and writing. The third is that we implement the CompletedSynchronously property. I’ll explain the implementation later.

 

 

Step 2. Creating a BeginEventHandler method, an EndEventHandler method, and an intermediate MyCallback

 

When a request comes in, the BeginEventHandler function will be called. This is when we will start our asynchronous Web service calls. The BeginEventHandler must return an IAsyncResult interface.

 

 

This method is being called for every HTTP request being handled by this virtual directory. Therefore, the first thing I do is check the actual path of the request and see if it is for the page that I am servicing or not.

 

My function is called with a couple interesting input parameters. The cb parameter is the callback function passed to me by ASP.NET. ASP.NET expects that when my asynchronous work has completed, the callback function it supplied me with will be called. That is ultimately how they will know when to call my EndEventHandler. The other interesting parameter is the extraData parameter that holds the state for ASP.NET when it calls me. I must return the state information when I invoke the callback function indicated by the cb parameter so I store it in the IAsyncResult class I created.

 

The MyCallback method is used to harvest the results of the asynchronous Web service call and relay the request to the EndEventHandler function.

 

Now is a good time to explain the implementation of the CompletedSynchronously property. ASP.NET will check the CompletedSynchronously property after BeginPreRequestHandlerExecute returns. If it is true, then ASP.NET calls EndPreRequestHandlerExecute. If it is false, then the method that checks the CompletedSynchronously property will return. It is up to the user to trigger cb.Invoke to go further. If cb.Invoke is called, then ASP.NET will check the CompletedSynchronously property again. If it is false, then ASP.NET will call EndPreRequestHandlerExecute and resume steps from a thread pool thread. If it is true, then the method that checks the CompletedSynchronously property will return. Now you understand why we need two “false” for the WebForm1.aspx page and one “true” for other pages. 

 

Step 3. Calling the AddOnPreRequestHandlerExecuteAsync method

 

The call to the AddOnPreRequestHandlerExecuteAsync method of the HttpApplication class registers PreRequestHandlerExecute notifications.

 

 

Step 4. Using the response data

 

Using the response data is quite trivial.

 

Making Web Service Calls from ASPX Pages: The Sequence of Operations of an Asynchronous PreRequestHandler Execution

The following is the sequence of operations of an asynchronous PreRequestHandler execution.

  • Thread A executes the Global constructor (implemented in Global.asax). In the constructor, the AddOnPreRequestHandlerExecuteAsync method is called. Then Thread A executes Application_Start, Application_BeginRequest, etc.
  • Thread B executes BeginPreRequestHandlerExecute.
  • Thread C executes MyCallback, EndPreRequestHandlerExecute, Page_Load, and Application_EndRequest.

Thread A, Thread B and Thread C might be different depending on how many tasks in the thread pool.

 

There is a gap between Thread B and Thread C because there must be some thread(s) to queue the Web service calls, make the calls, receive the responses, and even launch a thread pool thread to execute MyCallback. At the first glance, one might argue that there is no thread gain because there always is (are) thread(s) sitting somewhere to do the tasks mentioned above even though Thread A and Thread B are freed. It is important to understand that the Web services “interface” is the XML message on the wire, not the class definition one may work with to process in VB or C#. Basically there is a dedicated group of threads that is responsible to queue the Web service calls, send and receive all SOAP messages. The following diagram illustrates that.

 

 

 

All the requests share the same group of threads. So we do have thread gain! This is the key why this approach is efficient.

Making Web Service Calls from ASPX Pages: Asynchronous Pages

The following are the steps for using an asynchronous page after adding a Web reference:

  1. Creating a class implementing IAsyncResult and a custom proxy class.
  2. Creating an asynchronous page.
  3. Implementing the BeginProcessRequest, EndProcessRequest, MyCallback methods.
  4. Deriving a page from the asynchronous page and using the response data.

 

The implementation of this approach is similar to that of the asynchronous PreRequestHandler execution approach. I’ll highlight and mention those differences.

 

Step 1. Creating a class implementing IAsyncResult and a custom proxy class

 

 

The only change made on Step 1 of the asynchronous PreRequestHandler execution approach is to store an HttpContext object. We will pass it in the base.ProcessRequest call later.

 

Step 2. Creating an asynchronous page

 

The Page class itself implements the IHttpHandler interface, and thus services requests synchronously. To change a given .aspx page to service requests asynchronously, it is necessary to implement IHttpAsyncHandler in the Page-derived class. Our asynchronous page will derive System.UI.Page and implement the IHttpAsyncHandler interface.

 

Handlers that implement the IHttpAsyncHandler interface must implement two additional methods besides the standard methods of IHttpHandler, which are implemented by System.UI.Page. The first, BeginProcessRequest, is called by the application class instead of directly calling the ProcessRequest. It is then up to the handler to launch a new thread to process the request and then immediately return from the BeginProcessRequest method, passing back a reference to a valid IAsyncResult instance so that the runtime knows the operation is complete. The other method, EndProcessRequest, is called when the request processing is complete and can be used to clean up any allocated resources if necessary.

 

 

Step 3. Implementing the BeginProcessRequest, EndProcessRequest, MyCallback methods

 

 

I highlight a few changes made on Step 2 of the asynchronous PreRequestHandler execution approach. We have to access Request indirectly through Context, otherwise ASP.NET will try to get Request through the call System.Web.UI.Page.get_Request while the Page object is not initialized correctly at that time. We also need to store context in the MyAsyncResult object. It is important that I invoke the base class scope of ProcessRequest (with the original signature as defined in the IHttpHandler interface), which performs the standard request processing of a page, this time it will be performed on the thread pool thread instead of the primary request thread.

 

Step 4. Deriving a page from the asynchronous page and using the response data.

 

Making Web Service Calls from ASPX Pages: Asynchronous PreRequestHandler Execution vs. Asynchronous Pages

Both approaches have no big differences on performance from my testing. An asynchronous page serves one page while an asynchronous PreRequestHandler execution serves all the pages. So an asynchronous PreRequestHandler execution normally has to filter pages. An asynchronous page might serve as the base class for a set of pages or a standalone page. Asynchronous pages have slightly advantages over asynchronous PreRequestHandler execution in this aspect.

 

As we noted before, the end point of the asynchronous page approach is after the Page_Load event (actually after the ProcessRequest call). This may cause problem if we try to do page redirects during the ProcessRequest process. Actually Server.Transfer doesn’t work though Response.Redirect works. This is a big drawback.

Making Web Service Calls from ASPX Pages: Server Control Events

Both asynchronous page approach and asynchronous PreRequestHandler execution approach make the response data of a Web service call available before a page is initialized. So both approaches work if you load a new page, or click on a hyperlink, or a LinkButton. How to deal with control events such as button click events? Say, you click on a button. The action that you need to do is to make several lengthy Web service calls and use the response data from the calls in the button click event handler. As you can see, it is too late to start either approach in the button click event handler.

 

If the event that you need to handle is a server control event, then you are able to use both approaches. The reason is that you are able to detect the event and the data associated with the event at either the BeginProcessRequest call or a BeginEventHandler call because the event is a server control event. The following is the code to detect a button click event.

 

 

With this code, I do make the response data of a Web service call available in the button click event handler.

Making Web Service Calls from ASPX Pages: A Heavily Loaded Site

If you detect that the thread pool is the bottleneck and the cause is some lengthy Web service calls, then first you should try the asynchronous approaches discussed before. That will improve the performance of your app significantly. If that doesn’t address your issue, then you should switch to IIS 6.0 if you still use IIS 5.0 or increase the size of the thread pool by changing the setting of your machine.config. Most likely you have a very heavily loaded site and you should scale out other applications on the same machine where the Web server is located. So the change made on the machine.config file will not affect on other applications.

Making Web Service Calls from ASPX Pages: Asynchronous PreRequestHandler Execution with Multiple Methods from Multiple Web Services

It is possible that you need to make multiple Web service calls from multiple Web services in order to load a page. Next I’ll shows you how to do that with the asynchronous PreRequestHandler execution approach. It is similar to do that with the asynchronous page approach.

 

Assume that I have two Web services: Service1 and Service2. Service1 has two methods: SlowMethod1 and FastMethod1. Service2 has two methods: SlowMethod2 and FastMethod2. To generate a page, I need to make calls to all the four methods. I’ll use the same four steps. I’ll highlight and mention those differences.

 

Step 1. Creating a class implementing IAsyncResult and a custom proxy class

 

 

Each proxy object will have a HashTable to store a bunch of IAsyncResult interfaces for calls on this proxy. Each key in the HashTable can also be used as the key for the result of the call stored in the request context.

 

Each MyAsyncResult object will have an ArrayList to store the references to the proxies. Each Global object will also have a count to track if all the calls are ready for harvest results. I increment the count each time when I make a Web service call and decrement the count each time when MyCallBack is invoked.

 

Step 2. Creating a BeginEventHandler method, an EndEventHandler method, and an intermediate MyCallback

 

 

 

Since the MyCallBack method calls might run on the different threads, multiple threads might access the count of my MyAsyncResult object. We use the lock statement to control access to the MyAsyncResult object proxy1.Res.

 

A unique MyAsyncResult object proxy1.Res is used in the BeginPreRequestHandlerExecute method because we make a bunch of asynchronous calls and the BeginPreRequestHandlerExecute method returns a single IAsyncResult interface. That is the reason why we wrap all the proxies in one MyAsyncResult object and each proxy object will have a HashTable to store a bunch of IAsyncResult interfaces for calls on this proxy.

 

When count equals to 0 in the MyCallback method, I harvest the response data for all the calls and make the Res.cb.Invoke call to relay the process.

 

Step 3. Calling the AddOnPreRequestHandlerExecuteAsync method

 

There is no change made.

 

Step 4. Using the response data

 

Using the response data is trivial.

 

Making Web Service Calls from Web Services: Responsiveness of ASP.NET Web Services

In this section, I’ll show you how to make use of asynchronous Web methods on the server side to create high performance ASP.NET Web services.

 

1. Responsiveness of ASP.NET Web services

 

A typical communication scenario is shown below.

               

A client calls Web service 1 and Web service 1 might need to get data from a remote database through a Web service call. Four components might sit on different machines and the calls made might be lengthy network calls.

 

In this section, we focus on the responsiveness of Web service 1. The scenario here is similar to the scenario where we make Web service calls from ASPX pages. So the user experience we focus on Web service 1 is to provide the (almost) same user experience in cases where heavy loads on Web service 1 happen, as experience that users normally have. Normally the thread pool is in fact the bottleneck. We need some ways to allow the thread that serves the original request to return to the thread pool while it’s doing a long-running task (making a lengthy Web service call, for example). This allows one more of the limited number of threads in the thread pool to execute, enhancing overall performance and scalability of the system. As we discussed before, this only works for a set of long-running tasks that there is a dedicated group of threads that is responsible to queue and handle the long-running tasks. Web service calls fall into the set.

 

The asynchronous PreRequestHandler execution approach works for making Web service calls from Web services, but the asynchronous page approach doesn’t work because Web services use the ASMX handler. However, there is an asynchronous support built into the ASMX handler. This is called asynchronous Web methods. Asynchronous Web methods were documented in [17]. Matt Powell discussed them in more details in [2]. Next I discuss asynchronous Web methods. See [2] and [17] in more details.

Making Web Service Calls from Web Services: What Are Asynchronous Web Methods

Each Web method has an implementation associated with it. The ASMX handler allows a Web method being implemented either synchronously or asynchronously. Implementing a Web method synchronously means that the Web method will run on the thread that serves the request originally. The Web method DelayedResponse was implemented synchronously. Implementing a Web method synchronously also means implementing the Web method normally or as usual.

 

A Web method is called an asynchronous Web method if it is implemented asynchronously. Implementing a Web method asynchronously allows the thread that serves the request originally to return to the thread pool and serve other requests. This allows one more of the limited number of threads in the thread pool to execute, enhancing overall performance and scalability of the system.

 

A Web method can not be implemented both synchronously and asynchronously. VS.NET will throw a compiling error if you provide both a synchronous implementation and an asynchronous implementation.

 

Implementing a Web method synchronously or asynchronously has nothing to do with clients. Clients will see the same WSDL and proxy class regardless which way a Web method is implemented.

Making Web Service Calls from Web Services: Implementing an Asynchronous Web Method

Implementing an asynchronous XML Web service method follows the .NET Framework asynchronous design pattern.

 

So if we had a Web method whose synchronous declaration looked like this:

 

 

Then an asynchronous declaration would look like this:

 

 

We split the synchronous method into two methods; each with the same base name - one with that name starting with Begin and the other End. The BeginLengthyProcedure function returns an IAsyncResult interface and takes as its last two input parameters an AsyncCallback, and an object respectively. The EndLengthyProcedure function takes as its only parameter an IAsyncResult interface. Both must be flagged with the WebMethod attribute. In the BeginLengthyProcedure function, I made an asynchronous Web service call. The call takes the same cb, a parameter for BeginLengthyProcedure, as its parameter. This will cause that the EndLengthyProcedure function is invoked when the DelayedResponse call completes. The EndLengthyProcedure function will harvest the result of the DelayedResponse call and return it.

 

The following code example demonstrates how to chain asynchronous calls when a Web service method makes more than one asynchronous call and the calls must execute sequentially.

 

 

We have Web services: Service1 with a Web method DelayedResponse and Service 2 with a Web method DelayedResponse2. The BeginLengthyProcedure method makes an asynchronous call to Service 1 and sets up an intermediate callback named ChainCallback to receive the results. That intermediate callback then asynchronously calls to Service 2 and The EndLengthyProcedure function will harvest the result of the DelayedResponse2 call and return it.

 

Making Web Service Calls from Web Services: Asynchronous Web Methods vs. Asynchronous PreRequestHandler Execution

Asynchronous Web methods provide an efficient mechanism within ASP.NET Web services for invoking calls to backend Web services without causing precious threads in the process thread pool to block while doing nothing. This approach applies not only to Web services, but also a number of asynchronous I/O operations for accessing streams, making Microsoft® Windows® Sockets calls, performing file I/O, interacting with other hardware devices, calling asynchronous methods. However, it will only work with the implementations of Web methods (Web service requests in other words). The PreRequestHandler approach will work for all types of ASP.NET requests, but it is a bit easier to program with the asynchronous support built into the ASMX handler than it is to program with the PreRequestHandler.

Conclusion and References

We reviewed the various options provided by the Microsoft .NET Framework for making Web service calls. Whenever you are executing any sort of lengthy process where performance is an issue, it is always a good practice to look into an asynchronous execution model. We focused on asynchronous execution models from three kinds of Web service clients: Windows Forms clients, ASPX pages, and Web services. You are able to develop high-performance Web service applications by applying those models.

 

References

 

  1. At Your Service: Asynchronous Web Service Calls over HTTP with the .NET Framework
  2. At Your Service: Server-Side Asynchronous Web Methods
  3. At Your Service: Performance Considerations for Making Web Service Calls from ASPX Pages
  4. At Your Service: Adding a Progress Bar to Your Web Service Client Application
  5. Microsoft .NET Compact Framework Background Processing Techniques
  6. Wonders of Windows Forms: Safe, Simple Multithreading in Windows Forms, Part 1
  7. Wonders of Windows Forms: Safe, Simple Multithreading in Windows Forms, Part 2
  8. Wonders of Windows Forms: Safe, Simple Multithreading in Windows Forms, Part 3
  9. Multithreaded .NET Web Service Clients
  10. Windows Forms: Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads
  11. ASP.NET Pipeline: Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code
  12. Essential ASP.NET with Examples in C#, Fritz Onion, Addison-Wesley, 2003
  13. Asynchronous Http Handlers
  14. The ASP Column: HTTP Modules
  15. HTTP Pipelines: Securely Implement Request Processing, Filtering, and Content Redirection with HTTP Pipelines in ASP.NET
  16. .NET Delegates: Making Asynchronous Method Calls in the .NET Environment
  17. .NET Framework SDK: Creating Asynchronous XML Web Service Methods
  18. .NET Framework SDK: Communicating with XML Web Services Asynchronously
  19. Chris Brumme: Asynchronous operations
  20. .NET Framework SDK: Asynchronous Programming Overview


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-19 8:22:37 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search