Asynchronous Call using WaitHandle
This approach utilizes a different technique, in that we have a wait handle
object. This object will wait until the web service returns. When the parent
thread gets to the function WaitOne
(or WaitAll
or
WaitOne
), it waits for the web service to return. After the web
service returns the results, then the parent thread process will continue.
string mLangInput = "English";
// Create an instance of the WebService
localhost.MyAsyncWebService webServ =
new localhost.MyAsyncWebService();
// Create an IAsyncResult object to hold results
IAsyncResult asyncResult;
// Make an Asynchronous Call
asyncResult = webServ.BeginMyWebMethod
(this.mLangInput, null, null);
// Do something while the WebService is doing its work
str1 = "Doing some work while the WebService is being called.";
// Call WaitHandle to wait for the web service method to return
WaitHandle wtHandle = asyncResult.AsyncWaitHandle;
wtHandle.WaitOne();
// Get the Result of the WebMethod (this occurs when
// WebService finished processing)
mLangResult = webServ.EndMyWebMethod(asyncResult);
// Display the results in a label
Label1.Text = str1 + this.mLangResult;
This process uses the Begin<WebServiceMethod>
(BeginMyWebMethod
)
and assigns the result to the IAsyncResult
instance, passing in method
parameters and null values for Callback
and asyncState
(as callback is not used). The WaitOne()
method causes the thread to wait for the results from
the web service. When the results from the web service are ready, then End<WebServiceMethod>
(EndMyWebMethod
) is called to retrieve the results.
Asynchronous Call (Fire and Forget)
Very often, there can arise certain situations where a web method does not return
any value. Also, a process may need to be kicked off the web server without waiting
for the results. We can better illustrate this with the help of the following
example. We will create an XML file using the CreateXmlFile
web method, passing in a value. Note: if there is any error while
creating an XML file at the web service end, then the web application cannot be
notified, as the results are not returned to the web app from the web service.
// WebService web method
using System.Web.Services.Protocols;
[SoapDocumentMethod(OneWay=true)]
[WebMethod()]
public void CreateXMLFile(string lang) //No return value
{
//. . . . . . . . . . .
}
Client Call:
string mLangsInput = "English";
// Create an instance of the WebService
localhost.MyAsyncWebService webServ =
new localhost.MyAsyncWebService();
// Make a Web Method Call to create an XMLFile
webServ.CreateXMLFile(mLangInput);
// Do some process while the web service is processing the request
System.Threading.Thread.Sleep(10000);
To support fire-and-forget method calls, web methods should have an attribute
SoapDocumentMethod
, with the OneWay
attribute set to
true
. SoapDocumentMethod
resides in the System.Web.Services.Protocols
namespace; make sure that this namespace was used in the web service. Fire and
forget methods cannot have any return values, as the client does not expect any
results. When you use fire and forget web methods, it does not really matter
whether you have chosen an asynchronous or synchronous process, as the parent thread
does not wait for the results.
WaitHandle
Object Methods
The WaitHandle
object has three important methods; WaitOne
, WaitAll, and WaitAny
.
Multiple calls can be made asynchronously to web services from a single parent
thread. Here is an example:
// Declare two instances of Web Service
localhost.MyAsyncWebService webServ1 =
new localhost.MyAsyncWebService();
localhost.MyAsyncWebService webServ2 =
new localhost.MyAsyncWebService();
// Declare two instances of IAsyncResult
IAsyncResult asyncResult1;
IAsyncResult asyncResult2;
// Make two Asynchronous Calls to Web Service
asyncResult1 = webServ1.BeginCreateXMLFile
(this.mLangInput, null, null);
asyncResult2 = webServ2.BeginCreateXMLFile
(this.mLangInput, null, null);
// Call WaitHandle to wait for the web service method to return
WaitHandle wtHandle = asyncResult.AsyncWaitHandle;
// Causes to Wait until both the calls are returned
wtHandle.WaitAll();
// Causes to Wait until any of the calls to be returned
// wtHandleAny();
Here, two calls were made asynchronously to web services. The WaitAll()
method causes the parent thread to wait for both (All
) of the asynchronous calls
to return before it can proceed. The WaitAny() method causes it
to just wait for any (Any
) asynchronous call to return. If only one asynchronous
call is made, then WaitOne()
is used. For more information on the
WaitHandle
object, look here
at MSDN.
Callback Vs. WaitHandle
The choice of which approach to use is application-driven. If the application
needs the results from the web service to be used in the later stages of the
thread, then the WaitHandle
is the best approach. For example, if
the web service queries a database and retrieves a value that needs to be used
in the parent process and then displays the result to the user, then WaitHandle
should be used. We need the parent thread to stop processing at a certain stage
so that we can use the results from the web service to do further computation
and display the final results. Most web apps come under this scenario. In all
other scenarios, we can use callback. Mostly Windows apps use this approach.
Conclusion
Asynchronous calls to web services will
significantly enhance performance because they enable parallel processing of the
parent thread and the web service call by using two separate threads. This will be
very effective, especially if the web service method takes a long time to
process, since it lets the parent thread continue while the web service is
doing its own process.
Related Links