This article has been
excerpted from book "A Programmer's Guide to ADO.NET in C#".
There are two ways to access web services from a client application synchronously and asynchronously. A synchronous Web service is like the one we
just executed in our client application. When a client is accessing a web
service synchronously, a client has to wait until it gets a response from the
web service. As we saw in our client application in the previous section, we're
accessing OrderRetrievalService synchronously. What if a web method takes a long
time in response? For instance, what if our InsertOrderFromNode method takes 10
minute in response and client has many other things to process? In the present
case, the client has to wait for 10 minute and can't execute any thing else
until getting a response from web service. In other words, a client's main
thread is busy with the Web service if the client is accessing a Web service
synchronously. Executing a web service asynchronously allows client application
to execute more than one thread simultaneously. In other words, by calling
accessing web services asynchronously, a client can continue to use the calling
thread while waiting for the XML web service to respond. To access Web services
asynchronously doesn't require any special configuration.
When adding a Web reference to a client application, VS.NET generates a proxy
class capable of calling an XML Web service both synchronously and
asynchronously. You can see the proxy reference of OrderRetrievalService by
expanding the mcb node in the Solution Explorer; the reference filename is
Reference.cs
To view the contents of the proxy file, right-click and select View Code. This
file stores information related to the web service and its methods. It also
contains the URL of the web service. You can find the following code in
Reference.cs as OrderRetrievalService.
///
<remarks/>
public Service1()
{
}
Other information this file stores is asynchronous method for every web method
published by a web service. For each web method, there are two contains a
corresponding Begin and End method. Therefore, for web method
InsertOrderFromNode, asynchronous calls are BeginInsertOrderFromNode and
EndInsertOrderFromNode. You can find the following methods in Reference.cs file:
///<remarks/>
public System.IAsyncResult
BeginInsertOrderFromNode
(System.Xml.XmlNode aNode,
System.AsyncCallback callback,
object asyncState)
{
return this.BeginInvoke("InsertOrderFromNode",
new object[] {
aNode}, callback, asyncState);
}
///
<remarks/>
public int
EndInsertOrderFromNode(System.IAsyncResult
asyncResult)
{
object[] results =
this.EndInvoke(asyncResult);
return ((int)(results[0]));
}
Asynchronous web service execution requires a two-step process. First, you tell
the Web service to begin execution by calling the Begin method. The second step,
calling the End method, completes the web service call and returns the response.
To call a web service asynchronously, a client thread can use a WaitHandle. When
you get to a place in your client code when you are required to wait for the
service to end, you call a WaitHandle there. Listing 8-9 is an example of how to
use the WaitHandle. You can also assign a WaitHandle a timeout period in case
the web service takes to long.
In Listing 8-9, the code is adding two customer orders, so it needs to call the
web service twice. The code starts by calling BeginInsertOrderFromNode on the
first order, which returns an AsyncronousResult object. You can also use the
same method, BeginInsertOrderFromNode, to begin the service for inserting a
second order. You can use the WaitHandles returned from these calls to create
the WaitHandle instance. When you require the client to wait for the service to
finish, you execute the Waithandle's WaitAll method. The WaitAll method waits
for all the asynchronous threads to complete before continuing execution of the
code in the client. In this method you also pass a timeout period of 15 minutes,
so you don't have to wait forever. When the wait has completed, you call the
EndInsertOrderFromNode for both asynchronous threads. In the case where you were
waiting for a return value, the End<method> call would also return the data.
Note: You need to add a reference of the System,Threading namespace to
the application because the WaitHandle class is defined in the System.Threading
namespace.
Listing 8-9. Using WaitHandle to make synchronous calls
private void
Button3_Click(object sender, System.EventArgs
e)
{
// create the order
information in XML from the Client TextBoxes
XmlDocument OrderInfo = new
XmlDocument();
OrderInfo.LoadXml(
"<Order>" +
"<OrderDate>" + TextBox1.Text +
"</OrderDate>" +
"<ShipName >" + TextBox2.Text + "</ShipName>"
+
"<ShipAddress>" + TextBox3.Text +
"</ShipAddress>" +
"<ShipCity>" + TextBox4.Text +
"</ShipCity>" +
"<ShipCountry>" + TextBox5.Text +
"</ShipCountry>" +
"<ShipPostalCode>" +
TextBox6.Text + "</ShipPostalCode >" +
"</Order>");
// Construct the Web
Service for entering an Order
mcb.Service1 OrderEntry = new
mcb.Service1();
// Call the
Asynchronous InsertOrderFromNode
IAsyncResult ws1 =
OrderEntry.BeginInsertOrderFromNode(
OrderInfo, null,
null);
// Change the order
information slightly
OrderInfo["Order"]["ShipName"].InnerText
= "Fred Estaire";
// Call another
Asynchronous InsertOrderFromNode Call
IAsyncResult ws2 =
OrderEntry.BeginInsertOrderFromNode(OrderInfo,
null, null);
// Construct an
array of wait Handle and call WaitHandle for a
// Maximum of 15
minutes
WaitHandle[] TheWaitHandle = {ws1.AsyncWaitHandle,
ws2.AsyncWaitHandle};
WaitHandle.WaitAll(TheWaitHandles, new
TimeSpan(0, 15, 0),
true);
// All the web
services have returned (or timed out)
// call end order on
both web service Threads
int orderid1 =
OrderEntry.EndInsertOrder(ws1);
int orderid2 =
OrderEntry.EndInsertOrder(ws2);
}
WaitHandles has a few modes. In the previous mode, WaitAll, the command will
wait until all services are completed (wait until ws1 and ws2 are completed).
You can also call WaitAny. In the case of WaitAny, the method will wait until
any of the services complete (wait until ws1 or ws2 is complete).
Conclusion
Hope this article would have helped you in understanding
Executing Asynchronous Web Services
See other articles on
the website also for further reference.
|
This essential guide
to Microsoft's ADO.NET overviews C#, then leads you toward deeper
understanding of ADO.NET. |