I've posted a
couple of entries on the new Async page and async task features of ASP.NET 2.0. One question that has been coming to mind lately is whether async tasks add any benefit for parallelizing asynchronous web service invocations?
Here's what I mean - you can use async tasks to issue multiple concurrent requests to web service endpoints as follows:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AsyncTaskVsAsyncWs.aspx.cs"
Inherits="PS.Samples.AsyncTaskVsAsyncWs" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<form id="form1" runat="server">
<asp:Label runat="server" ID="resultsLabel" />
</form>
</body>
</html>
// Code behind file
namespace PS.Samples
{
public partial class AsyncTaskVsAsyncWs : Page
{
WebService1 _ws1 = new WebService1();
WebService1 _ws2 = new WebService2();
protected void Page_Load(object sender, EventArgs e)
{
PageAsyncTask task1 = new PageAsyncTask(
delegate (object src, EventArgs ea, AsyncCallback cb, object state)
{ return _ws1.BeginHelloWorld(cb, state); },
delegate (object src, EventArgs ea, AsyncCallback cb, object state)
{ resultsLabel.Text += _ws1.EndHelloWorld(cb, state); },
null, null);
PageAsyncTask task2 = new PageAsyncTask(
delegate (object src, EventArgs ea, AsyncCallback cb, object state)
{ return _ws2.BeginHelloWorld2(cb, state); },
delegate (object src, EventArgs ea, AsyncCallback cb, object state)
{ resultsLabel.Text += _ws2.EndHelloWorld2(cb, state); },
null, null);
RegisterAsyncTask(task1);
RegisterAsyncTask(task2);
}
}
}
Or alternatively, you can simply invoke the async web services directly (using the same .aspx file):
// Code behind file
namespace PS.Samples
{
public partial class AsyncTaskVsAsyncWs : Page
{
WebService1 _ws1 = new WebService1();
WebService1 _ws2 = new WebService2();
protected void Page_Load(object sender, EventArgs e)
{
IAsyncResult iar1 = _ws1.BeginHelloWorld(null, null);
IAsyncResult iar2 = _ws2.BeginHelloWorld2(null, null);
resultsLabel.Text += _ws1.EndHelloWorld(iar1);
resultsLabel.Text += _ws2.EndHelloWorld2(iar2);
}
}
}
In both cases, the primary request thread is blocked while the asynchronous requests are made, and in both cases the total time taken is the longest web service call (not the sum as it would be sequentially), which is the big win. The second technique is obviously quite a bit simpler.
From what I can tell, the big advantage to using async tasks to do this are:
-
You can make the page itself asynchronous by just setting the attribute in the @Page directive
-
You can specify a timeout delegate and have a recovery plan if a call takes too long (you could do this by calling WaitOne on the IAsyncResult's AsyncWaitHandle too, but that would take some more coding.
Besides that, they amount to pretty much the same thing, so if you just want to call multiple concurrent web services, the second technique seems the right way to go (since it's simpler). Anyone see any other reasons I'm missing?
Posted
Jun 15 2005, 10:39 AM
by
fritz-onion