设为首页
加入收藏
站内地图
旧版入口
当前位置:首页 > 站长学院 > 网络编程 > ASP.NET

ASP.NET 2.0 中的异步页功能应用 3

作者:佚名 出处:网络转载 时间:11-10 点击:

内容载入中...
     异步调用 Web 服务
  
    另一个通常由 ASP.net Web 页执行的、与 I/O 相关的任务是调出 Web 服务。由于 Web 服务调用花费较长时间才能返回,因此,执行它们的页是用于异步处理的理想选择。
  
  图5
  
  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();
   }
  }
  
  
  
    图 5 显示生成调出 Web 服务的异步页的方式。它使用图 1 和 图 4 中相同的 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 的返回值。
  
    图 6 展示使用 MethodAsync 模式异步调用 Web 服务的 GetTitles 方法的代码隐藏类。从功能上讲,该页等同于图 5 中的页。但其内部实现则大为不同。AsyncWSInvoke2.ASPx 包括一个 @ Page Async=“true” 指令,类似于 AsyncWSInvoke1.ASPx。但是,AsyncWSInvoke2.ASPx.cs 并不调用 AddOnPreRenderCompleteAsync;它注册一个用于 GetTitlesCompleted 事件的处理程序,并调用 Web 服务代理上的 GetTitlesAsync。ASP.NET 仍然延迟呈现该页,直到 GetTitlesAsync 完成。在内部,当异步调用开始以及完成时,它使用 System.Threading.SynchronizationContext 的一个实例(2.0 的一个新类)接收通知。
  
  图6
  
  using System;
  using System.Data;
  using System.Configuration;
  using System.Web;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  public partial class AsyncWSInvoke2 : 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);
  
    // Call the Web service asynchronously
    _ws = new WS.PubsWebService();
    _ws.GetTitlesCompleted += new
    WS.GetTitlesCompletedEventHandler(GetTitlesCompleted);
    _ws.Url = new Uri(Request.Url, "Pubs.asmx").ToString();
    _ws.UseDefaultCredentials = true;
    _ws.GetTitlesAsync();
   }
  }
  
  void GetTitlesCompleted(Object source,
  WS.GetTitlesCompletedEventArgs e)
  {
   _ds = e.Result;
  }
  
  protected void Page_PreRenderComplete(object sender, EventArgs e)
  {
   Output.DataSource = _ds;
   Output.DataBind();
  }
  
  public override void Dispose()
  {
   if (_ws != null) _ws.Dispose();
   base.Dispose();
  }
  }
  
  
  
    使用 MethodAsync 而非 AddOnPreRenderCompleteAsync 实现异步页有两个优势。首先,MethodAsync 将模拟、区域性和 HttpContext.Current 注入 MethodCompleted 事件处理程序,而 AddOnPreRenderCompleteAsync 则不然。其次,如果该页进行多个异步调用,而且必须延迟呈现直到所有调用完成,则使用 AddOnPreRenderCompleteAsync 要求您生成一个在所有调用完成前保持无信号状态的 IasyncResult。使用 MethodAsync,这样的操作就不是必需的;您只需放置这些调用(数量不限),ASP.NET 引擎延迟该呈现阶段,直到最后一个调用返回。
  
  
  
    。

收藏本文:
】【打印页面】【推荐给朋友】【关闭窗口

站长学院

推荐信息