【IT168技术文档】
异步调用 Web 服务
另一个通常由 ASP.NET Web 页执行的、与 I/O 相关的任务是调出 Web 服务。由于 Web 服务调用花费较长时间才能返回,因此,执行它们的页是用于异步处理的理想选择。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class AsyncWSInvoke1 : System.Web.UI.Page
{
private WS.PubsWebService _ws;
private DataSet _ds;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Hook PreRenderComplete event for data binding
this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
// Register async methods
AddOnPreRenderCompleteAsync(new BeginEventHandler
(BeginAsyncOperation),new EndEventHandler(EndAsyncOperation)
);
}
}
IAsyncResult BeginAsyncOperation (object sender,
EventArgs e, AsyncCallback cb, object state)
{
_ws = new WS.PubsWebService();
// Fix up URL for call to local VWD-hosted Web service
_ws.Url = new Uri(Request.Url, "Pubs.asmx").ToString();
_ws.UseDefaultCredentials = true;
return _ws.BeginGetTitles (cb, state);
}
void EndAsyncOperation(IAsyncResult ar)
{
_ds = _ws.EndGetTitles(ar);
}
protected void Page_PreRenderComplete(object sender, EventArgs e)
{
Output.DataSource = _ds;
Output.DataBind();
}
public override void Dispose()
{
if (_ws != null) _ws.Dispose();
base.Dispose();
}
}
上面显示生成调出 Web 服务的异步页的方式。它使用AddOnPreRenderCompleteAsync 机制。该页的 Begin 方法通过调用 Web 服务代理的异步 Begin 方法启动一个异步 Web 服务调用。该页的 End 方法在私有字段中缓存对 Web 方法返回的 DataSet 的引用,并且 PreRenderComplete 处理程序将 DataSet 绑定到 GridView。作为参考,该调用的目标 Web 方法如以下代码所示:
[WebMethod]
public DataSet GetTitles ()
{
string connect = WebConfigurationManager.ConnectionStrings
["PubsConnectionString"].ConnectionString;
SqlDataAdapter adapter = new SqlDataAdapter
("SELECT title_id, title, price FROM titles", connect);
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds;
}
这只是其中一种方式,但并不是唯一的方式。.NET Framework 2.0 Web 服务代理支持两种对 Web 服务进行异步调用的机制。一个是 .NET Framework 1.x 和 2.0 Web 服务代理中的每方法 Begin 和 End 方法。另一个是仅由 .NET Framework 2.0 的 Web 服务代理提供的新 MethodAsync 方法和 MethodCompleted 事件。
如果一个 Web 服务有一个名为 Foo 的方法,那么除了具有名为 Foo、BeginFoo 和 EndFoo 的方法外,.NET Framework 版本 2.0 Web 服务代理还包括名为 FooAsync 的方法和名为 FooCompleted 的事件。可以通过注册 FooCompleted 事件的处理程序并调用 FooAsync 来异步调用 Foo,如下所示:
proxy.FooCompleted += new FooCompletedEventHandler (OnFooCompleted);
proxy.FooAsync (...);
...
void OnFooCompleted (Object source, FooCompletedEventArgs e)
{
// Called when Foo completes
}
当异步调用由于 FooAsync 完成而开始时,将引发 FooCompleted 事件,从而导致调用 FooCompleted 事件处理程序。包装该事件处理程序 (FooCompletedEventHandler) 的委托和传递给它的第二个参数 (FooCompletedEventArgs) 都随 Web 服务代理一起生成。可通过 FooCompletedEventArgs.Result 访问 Foo 的返回值。