Professional ASP.NET Web Services : Asynchronous Programmingby Wrox Press.
Overview :
To wait or not to wait; that is the question! Whether or not to implement asynchronous
processing is one of the fundamental issues that a developer must answer when invoking
function calls across process boundaries. Given that the option to invoke an asynchronous
call is available, the programmer has to weigh the relative ease of coding synchronous
calls with its inherent drawback - when a synchronous call is made, the calling thread is
blocked and has to wait until the function completes. In many instances, this is an
acceptable shortcoming, as in the case when a program's logic flow should not continue
until data is retrieved from a database. Asynchronous processing, on the other hand, allows
more parallelism. A thread that initiates an asynchronous call is not blocked and can
therefore do almost any computation while the method is in transit. The case for
asynchronous processing becomes very compelling in the enterprise computing space where
systems need to handle hundreds of thousands of function call requests and synchronicity
may become a barrier to scalability.
Web Services support both synchronous and asynchronous communication between the client
application and the server hosting the service. Since both are supported, the developer is
challenged with deciding which type of process to initiate in their application. In this
chapter, we're going to dive into the subject of synchronous and asynchronous programming
as it pertains to ASP.NET Web Services. We'll explore the mechanics of invoking Web
Services via an asynchronous mechanism. We'll also look into the .NET framework and how it
provides the infrastructure for asynchronous processing.
So, the topics for this chapter are:
- Synchronous versus asynchronous invocations
- Asynchronous design patterns in .NET
- How to invoke Web Services asynchronously
- What to consider when developing asynchronous Web Service calls
Synchronous Versus Asynchronous Invocations :
As we learned in Chapter 2, the .NET framework shields the programmer from the
complexities of generating a remote procedure call (RPC) to a Web Service hosted on
another server. As far as we are concerned, they are simply making a method call to another
component. The mechanism for invoking the method call looks the same whether the server
component is within the application's assembly or many miles away running on another
machine.
Despite their similarities on the surface, the underlying plumbing used to invoke a Web
Service is very different from an in-process function call. In the case of a Web Service,
the function call is packaged into a SOAP message and marshaled across the Internet via the
HTTP protocol. Because of the inherent nature of the Internet, performance of the RPC call
to the Web Service can vary greatly from one call to the next. The design choices you make
when developing your Web Service client application can make a big difference in how your
users will perceive application availability and performance.
In this section, we'll compare the merits and shortcomings of both the synchronous and
asynchronous approaches to calling Web Services. We'll also learn how to actually develop
client applications that make use of the asynchronous mechanisms built into the .NET
framework. This will set the stage for a deeper discussion of asynchronous processing in
the subsequent sections.
The Case for Synchronous Processing :
Synchronous operations consist of component or function calls that operate in lockstep.
A synchronous call blocks a process until the operation completes. Only then will the next
line of execution be invoked. There are many examples in life that model this pattern of
behavior. The cafeteria line at your local restaurant, for example, behaves in a synchronous
fashion. Customers are serviced one at a time. While they are in line, they are blocked
from conducting other activities, and they wait until all their food choices are served
before they can continue with their lunch-break. Of course, after waiting for a very
long time they might give up and leave. Here's a diagram illustrating the concept of
synchronous processes:

Synchronous Processes
As you can see, the procedure for making synchronous calls is straightforward:
- The client obtains an interface pointer to the server object and calls a method
through that pointer
- The client waits until the server either completes the method call, or if there
is no response for a given period of time the client raises an error
- Only after the method call returns is the client free to continue with its
processing
It is this simplicity that makes synchronous processes a compelling choice. Most
of the time, the performance achieved from method calls is acceptable and does not
warrant the extra overhead required for concurrent processing. In fact, most of the
function calls in the .NET framework are synchronous to minimize problems that can
arise from asynchronous message processing. Likewise, the method calls you will be
implementing will be done in a synchronous fashion in most cases.
Asynchronous message passing, on the other hand, is more difficult to code and
introduces several problems. What happens if the method call is not delivered to the
server object successfully? The calling process does not wait for delivery of the
message, and thus never hears about the error. The operating system has to provide
the infrastructure for reporting such errors, or worse, the programmer may have to
write special code to handle such cases. Another related problem is how will the
calling application discover the completion of the called function? The application
will either have to create a polling mechanism, event trigger, or callback method in
order to be later notified of the operation.
Because synchronous messaging is so easy to implement, you may be tempted to take
the simple route and always use a synchronous mechanism when invoking a Web Service
from your client code. Consider your choice carefully because this decision will have
an impact on how your client application will perform. When implemented properly, using
asynchronous communication may improve system usage and avoid delays on the client side,
while waiting for the Web Service results.
When Asynchronous Processing Is Better :
When method calls are invoked across process and machine boundaries via an RPC mechanism,
it's oftentimes a likely candidate for asynchronous processing. This is definitely true
in the case of Web Services where the remote procedure call is sent via HTTP and must
deal with issues such as bandwidth constraints and network latency.
What makes asynchronous method invocations a good choice for communicating with Web
Services? An asynchronous operation will not block the calling thread, which only
initiates the operation. The calling application must then discover completion of the
call by polling, by software interrupt, or by waiting explicitly for completion later.
An asynchronous operation will need to return a call or transaction ID if the calling
application needs to be later notified about the operation. At notification time, this
ID would be placed in some global location or passed as an argument to a handle or wait
call. Here is a diagram illustrating the concept of an asynchronous process: Overview :
To wait or not to wait; that is the question! Whether or not to implement asynchronous
processing is one of the fundamental issues that a developer must answer when invoking
function calls across process boundaries. Given that the option to invoke an asynchronous
call is available, the programmer has to weigh the relative ease of coding synchronous
calls with its inherent drawback - when a synchronous call is made, the calling thread is
blocked and has to wait until the function completes. In many instances, this is an
acceptable shortcoming, as in the case when a program's logic flow should not continue
until data is retrieved from a database. Asynchronous processing, on the other hand, allows
more parallelism. A thread that initiates an asynchronous call is not blocked and can
therefore do almost any computation while the method is in transit. The case for
asynchronous processing becomes very compelling in the enterprise computing space where
systems need to handle hundreds of thousands of function call requests and synchronicity
may become a barrier to scalability.
Web Services support both synchronous and asynchronous communication between the client
application and the server hosting the service. Since both are supported, the developer is
challenged with deciding which type of process to initiate in their application. In this
chapter, we're going to dive into the subject of synchronous and asynchronous programming
as it pertains to ASP.NET Web Services. We'll explore the mechanics of invoking Web
Services via an asynchronous mechanism. We'll also look into the .NET framework and how it
provides the infrastructure for asynchronous processing.
So, the topics for this chapter are:
- Synchronous versus asynchronous invocations
- Asynchronous design patterns in .NET
- How to invoke Web Services asynchronously
- What to consider when developing asynchronous Web Service calls
Synchronous Versus Asynchronous Invocations :
As we learned in Chapter 2, the .NET framework shields the programmer from the
complexities of generating a remote procedure call (RPC) to a Web Service hosted on
another server. As far as we are concerned, they are simply making a method call to another
component. The mechanism for invoking the method call looks the same whether the server
component is within the application's assembly or many miles away running on another
machine.
Despite their similarities on the surface, the underlying plumbing used to invoke a Web
Service is very different from an in-process function call. In the case of a Web Service,
the function call is packaged into a SOAP message and marshaled across the Internet via the
HTTP protocol. Because of the inherent nature of the Internet, performance of the RPC call
to the Web Service can vary greatly from one call to the next. The design choices you make
when developing your Web Service client application can make a big difference in how your
users will perceive application availability and performance.
In this section, we'll compare the merits and shortcomings of both the synchronous and
asynchronous approaches to calling Web Services. We'll also learn how to actually develop
client applications that make use of the asynchronous mechanisms built into the .NET
framework. This will set the stage for a deeper discussion of asynchronous processing in
the subsequent sections.
The Case for Synchronous Processing :
Synchronous operations consist of component or function calls that operate in lockstep.
A synchronous call blocks a process until the operation completes. Only then will the next
line of execution be invoked. There are many examples in life that model this pattern of
behavior. The cafeteria line at your local restaurant, for example, behaves in a synchronous
fashion. Customers are serviced one at a time. While they are in line, they are blocked
from conducting other activities, and they wait until all their food choices are served
before they can continue with their lunch-break. Of course, after waiting for a very
long time they might give up and leave. Here's a diagram illustrating the concept of
synchronous processes:

Synchronous Processes
As you can see, the procedure for making synchronous calls is straightforward:
- The client obtains an interface pointer to the server object and calls a method
through that pointer
- The client waits until the server either completes the method call, or if there
is no response for a given period of time the client raises an error
- Only after the method call returns is the client free to continue with its
processing
It is this simplicity that makes synchronous processes a compelling choice. Most
of the time, the performance achieved from method calls is acceptable and does not
warrant the extra overhead required for concurrent processing. In fact, most of the
function calls in the .NET framework are synchronous to minimize problems that can
arise from asynchronous message processing. Likewise, the method calls you will be
implementing will be done in a synchronous fashion in most cases.
Asynchronous message passing, on the other hand, is more difficult to code and
introduces several problems. What happens if the method call is not delivered to the
server object successfully? The calling process does not wait for delivery of the
message, and thus never hears about the error. The operating system has to provide
the infrastructure for reporting such errors, or worse, the programmer may have to
write special code to handle such cases. Another related problem is how will the
calling application discover the completion of the called function? The application
will either have to create a polling mechanism, event trigger, or callback method in
order to be later notified of the operation.
Because synchronous messaging is so easy to implement, you may be tempted to take
the simple route and always use a synchronous mechanism when invoking a Web Service
from your client code. Consider your choice carefully because this decision will have
an impact on how your client application will perform. When implemented properly, using
asynchronous communication may improve system usage and avoid delays on the client side,
while waiting for the Web Service results.
When Asynchronous Processing Is Better :
When method calls are invoked across process and machine boundaries via an RPC mechanism,
it's oftentimes a likely candidate for asynchronous processing. This is definitely true
in the case of Web Services where the remote procedure call is sent via HTTP and must
deal with issues such as bandwidth constraints and network latency.
What makes asynchronous method invocations a good choice for communicating with Web
Services? An asynchronous operation will not block the calling thread, which only
initiates the operation. The calling application must then discover completion of the
call by polling, by software interrupt, or by waiting explicitly for completion later.
An asynchronous operation will need to return a call or transaction ID if the calling
application needs to be later notified about the operation. At notification time, this
ID would be placed in some global location or passed as an argument to a handle or wait
call. Here is a diagram illustrating the concept of an asynchronous process:
|