青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

道。道。道

安全特性不等于安全的特性

   :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理

常用鏈接

搜索

  •  

最新評(píng)論

  ASP.NET 2.0 提供了大量新功能,其中包括聲明性數(shù)據(jù)綁定和母版頁(yè),成員和角色管理服務(wù)等。但我認(rèn)為最棒的功能是異步頁(yè),接下來(lái)讓我告訴您其中的原因。
  當(dāng) ASP.NET 接收針對(duì)頁(yè)的請(qǐng)求時(shí),它從線(xiàn)程池中提取一個(gè)線(xiàn)程并將請(qǐng)求分配給該線(xiàn)程。一個(gè)普通的(或同步的)頁(yè)在該請(qǐng)求期間保留線(xiàn)程,從而防止該線(xiàn)程用于處理其他請(qǐng)求。如果一個(gè)同步請(qǐng)求成為 I/O 綁定(例如,如果它調(diào)用一個(gè)遠(yuǎn)程 Web 服務(wù)或查詢(xún)一個(gè)遠(yuǎn)程數(shù)據(jù)庫(kù),并等待調(diào)用返回),那么分配給該請(qǐng)求的線(xiàn)程在調(diào)用返回之前處于掛起狀態(tài)。這影響了可伸縮性,原因是線(xiàn)程池的可用線(xiàn)程是有限的。如果所有請(qǐng)求處理線(xiàn)程全部阻塞以等待 I/O 操作完成,則其他請(qǐng)求排入隊(duì)列等待線(xiàn)程釋放。最好的情況是吞吐量減少,因?yàn)檎?qǐng)求等待較長(zhǎng)的時(shí)間才能得到處理。最壞的情況則是該隊(duì)列填滿(mǎn),并且 ASP.NET 因 503“Server Unavailable”錯(cuò)誤使后續(xù)請(qǐng)求失敗。

  異步頁(yè)為由 I/O 綁定的請(qǐng)求引起的問(wèn)題提供優(yōu)秀的解決方案。頁(yè)處理從線(xiàn)程池線(xiàn)程開(kāi)始,但是當(dāng)一個(gè)異步 I/O 操作開(kāi)始響應(yīng) ASP.NET 的信號(hào)之后,該線(xiàn)程返回線(xiàn)程池。當(dāng)該操作完成時(shí),ASP.NET 從線(xiàn)程池提取另一個(gè)線(xiàn)程,并完成該請(qǐng)求的處理。由于線(xiàn)程池線(xiàn)程得到了更高效的使用,因此提高了可伸縮性。那些掛起等待 I/O 完成的線(xiàn)程現(xiàn)在可用于服務(wù)其他請(qǐng)求。直接的受益方是不執(zhí)行長(zhǎng)時(shí)間 I/O 操作并因此可以快速進(jìn)出管線(xiàn)的請(qǐng)求。長(zhǎng)時(shí)間等待進(jìn)入管線(xiàn)會(huì)對(duì)此類(lèi)請(qǐng)求的性能帶來(lái)不小的負(fù)面影響。
  ASP.NET 2.0 Beta 2 異步頁(yè)基礎(chǔ)結(jié)構(gòu)的相關(guān)文檔很少。讓我們展望一下異步頁(yè)的前景,從而彌補(bǔ)這點(diǎn)不足。請(qǐng)記住,本專(zhuān)欄涉及 ASP.NET 2.0 和 .NET Framework 2.0 的測(cè)試版本。。

  ASP.NET 1.x 中的異步頁(yè)

  ASP.NET 1.x 本質(zhì)上不支持異步頁(yè),但是通過(guò)堅(jiān)韌的努力和不懈地創(chuàng)新可以生成異步頁(yè)。有關(guān)更多概述信息,請(qǐng)參閱相關(guān)資料

  這里的技巧是,在一個(gè)頁(yè)的代碼隱藏類(lèi)中實(shí)現(xiàn) IhttpAsyncHandler,從而提示 ASP.NET 通過(guò)調(diào)用 IHttpAsyncHandler.BeginProcessRequest 來(lái)處理請(qǐng)求,而不是通過(guò)調(diào)用該頁(yè)的 IHttpHandler.ProcessRequest 方法。然后,您的 BeginProcessRequest 實(shí)現(xiàn)可以啟動(dòng)另一個(gè)線(xiàn)程。該線(xiàn)程調(diào)用 base.ProcessRequest,使得頁(yè)進(jìn)入其常規(guī)請(qǐng)求處理生命周期(完成諸如 Load 和 Render 的事件),但是在非 ThreadPool 線(xiàn)程上例外。同時(shí),啟動(dòng)新線(xiàn)程之后 BeginProcessRequest 立即返回,從而允許執(zhí)行 BeginProcessRequest 的線(xiàn)程返回線(xiàn)程池。

  這是基本思想,但細(xì)節(jié)中還有很多注意事項(xiàng)。其中,您需要實(shí)現(xiàn) IAsyncResult,并從 BeginProcessRequest 中返回它。這通常意味著創(chuàng)建一個(gè) ManualResetEvent 對(duì)象,并且當(dāng) ProcessRequest 在后臺(tái)線(xiàn)程中返回時(shí)向其發(fā)送信號(hào)。此外,您必須提供調(diào)用 base.ProcessRequest 的線(xiàn)程。遺憾的是,多數(shù)用于將工作移到后臺(tái)線(xiàn)程的常規(guī)技術(shù)(包括 Thread.Start、ThreadPool.QueueUserWorkItem 和異步委托)在 ASP.NET 應(yīng)用程序中都是起反作用的,因?yàn)樗鼈兓蛘邚木€(xiàn)程池“偷盜”線(xiàn)程,或者有不受限制的線(xiàn)程增長(zhǎng)的危險(xiǎn)。正確的異步頁(yè)實(shí)現(xiàn)使用自定義線(xiàn)程池,但自定義線(xiàn)程池類(lèi)不容易編寫(xiě)。

  主要是在 ASP.NET 1.x 中生成異步頁(yè)并非不可能,而是有些乏味。在嘗試一、兩次之后,您不禁會(huì)想一定會(huì)有更好的方法。目前,這個(gè)好方法就是 ASP.NET 2.0。

  ASP.NET 2.0 中的異步頁(yè)

  ASP.NET 2.0 極大地簡(jiǎn)化了生成異步頁(yè)的方式。首先使用該頁(yè)的 @ Page 指令引入 Async=“true” 屬性,如下所示:

  在后臺(tái),這會(huì)通知 ASP.NET 在該頁(yè)中實(shí)現(xiàn) IhttpAsyncHandler。接下來(lái),您在該頁(yè)生存期的早期(例如,在 Page_Load 時(shí))調(diào)用新的 Page.AddOnPreRenderCompleteAsync 方法來(lái)注冊(cè)一個(gè) Begin 方法和一個(gè) End 方法,如以下代碼所示:

AddOnPreRenderCompleteAsync (
            new BeginEventHandler(MyBeginMethod),
            new EndEventHandler (MyEndMethod)
            );

  接下來(lái)的操作比較有趣。該頁(yè)經(jīng)歷其常規(guī)處理生命周期,直到 PreRender 事件剛剛引發(fā)之后。然后,ASP.NET 調(diào)用使用 AddOnPreRenderCompleteAsync 注冊(cè)的 Begin 方法。Begin 方法的任務(wù)是啟動(dòng)諸如數(shù)據(jù)庫(kù)查詢(xún)或 Web 服務(wù)調(diào)用的異步操作,并立即返回。此時(shí),分配給該請(qǐng)求的線(xiàn)程返回到線(xiàn)程池。此外,Begin 方法返回 IAsyncResult,它允許 ASP.NET 確定異步操作完成的時(shí)間,這個(gè)時(shí)候 ASP.NET 從線(xiàn)程池提取線(xiàn)程并調(diào)用 End 方法。當(dāng) End 返回之后,ASP.NET 執(zhí)行該頁(yè)生命周期其余的部分,包括呈現(xiàn)階段。在 Begin 返回以及調(diào)用 End 之間,該請(qǐng)求處理線(xiàn)程可以自由地服務(wù)于其他請(qǐng)求,直至調(diào)用 End 且延遲呈現(xiàn)為止。由于 2.0 版的 .NET Framework 提供多種執(zhí)行異步操作的方式,因此,您甚至無(wú)需實(shí)現(xiàn) IasyncResult。反之,F(xiàn)ramework 替您實(shí)現(xiàn)。

  圖 1 中的代碼隱藏類(lèi)提供一個(gè)示例。響應(yīng)頁(yè)包含一個(gè) ID 為“Output”的 Label 控件。該頁(yè)使用 System.Net.HttpWebRequest 類(lèi)提取 http://MSDN.microsoft.com 的內(nèi)容。然后,它分析返回的 HTML,并將它發(fā)現(xiàn)的全部 HREF 目標(biāo)列表寫(xiě)出到 Label 控件。

圖1

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public partial class AsyncPage : System.Web.UI.Page
{
 private WebRequest _request;

 void Page_Load (object sender, EventArgs e)
 {
  AddOnPreRenderCompleteAsync (
   new BeginEventHandler(BeginAsyncOperation),
   new EndEventHandler (EndAsyncOperation)
  );
 }

 IAsyncResult BeginAsyncOperation (object sender, EventArgs e,
AsyncCallback cb, object state)
 {
  _request = WebRequest.Create("http://msdn.microsoft.com");
  return _request.BeginGetResponse (cb, state);
 }
 void EndAsyncOperation (IAsyncResult ar)
 {
  string text;
  using (WebResponse response = _request.EndGetResponse(ar))
  {
   using (StreamReader reader = new StreamReader(response.GetResponseStream()))
   {
    text = reader.ReadToEnd();
   }
  }

  Regex regex = new Regex ("href\\s*=\\s*\"([^\"]*)\"", RegexOptions.IgnoreCase);
  MatchCollection matches = regex.Matches(text);

  StringBuilder builder = new StringBuilder(1024);
  foreach (Match match in matches)
  {
   builder.Append (match.Groups[1]);
   builder.Append("<br/>");
  }

  Output.Text = builder.ToString ();
 }
}

 


  由于 HTTP 請(qǐng)求需要較長(zhǎng)時(shí)間才能返回,因此,AsyncPage.aspx.cs 異步執(zhí)行對(duì)它的處理。它在 Page_Load 中注冊(cè) Begin 和 End 方法,并且在 Begin 方法中,它調(diào)用 HttpWebRequest.BeginGetResponse 啟用一個(gè)異步 HTTP 請(qǐng)求。BeginAsyncOperation 將由 BeginGetResponse 返回的 IAsyncResult 返回到 ASP.NET,導(dǎo)致當(dāng) HTTP 請(qǐng)求完成時(shí),ASP.NET 調(diào)用 EndAsyncOperation。EndAsyncOperation 進(jìn)而分析該內(nèi)容并將結(jié)果寫(xiě)入 Label 控件,之后進(jìn)行呈現(xiàn),并且 HTTP 響應(yīng)返回到瀏覽器。


圖 2 同步和異步頁(yè)處理

  圖 2 說(shuō)明 ASP.NET 2.0 同步和異步頁(yè)之間的區(qū)別。當(dāng)請(qǐng)求同步頁(yè)時(shí),ASP.NET 為該請(qǐng)求分配線(xiàn)程池中的一個(gè)線(xiàn)程,并在該線(xiàn)程上執(zhí)行頁(yè)。如果該請(qǐng)求停止執(zhí)行 I/O 操作,則掛起線(xiàn)程,直到完成操作,從而可以完成該頁(yè)的生命周期。相反,異步頁(yè)通常通過(guò) PreRender 事件執(zhí)行。然后,調(diào)用使用 AddOnPreRenderCompleteAsync 注冊(cè)的 Begin 方法,之后,該請(qǐng)求處理線(xiàn)程返回線(xiàn)程池。Begin 啟動(dòng)一個(gè)異步 I/O 操作,當(dāng)該操作完成時(shí),ASP.NET 從線(xiàn)程池提取另一個(gè)線(xiàn)程并調(diào)用 End 方法,并且在該線(xiàn)程上執(zhí)行該頁(yè)生命周期的其余部分。


圖 3 跟蹤輸出顯示異步頁(yè)的異步點(diǎn)

  對(duì) Begin 的調(diào)用標(biāo)記該頁(yè)的“異步點(diǎn)”。圖 3 中的跟蹤準(zhǔn)確顯示異步點(diǎn)發(fā)生在何處。如果調(diào)用,則必須在異步點(diǎn)之前調(diào)用 AddOnPreRenderCompleteAsync — 即,不晚于該頁(yè)的 PreRender 事件。

  異步數(shù)據(jù)綁定

  通常情況下,ASP.NET 頁(yè)并不使用 HttpWebRequest 直接請(qǐng)求其他頁(yè),但它們通常查詢(xún)數(shù)據(jù)庫(kù)并對(duì)結(jié)果進(jìn)行數(shù)據(jù)綁定。因此,您將如何使用異步頁(yè)執(zhí)行異步數(shù)據(jù)綁定呢?圖 4 中的代碼隱藏類(lèi)顯示進(jìn)行此操作的一種方式。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;

public partial class AsyncDataBind : System.Web.UI.Page
{
 private SqlConnection _connection;
 private SqlCommand _command;
 private SqlDataReader _reader;

 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)
 {
  string connect = WebConfigurationManager.ConnectionStrings
["PubsConnectionString"].ConnectionString;
  _connection = new SqlConnection(connect);
  _connection.Open();
  _command = new SqlCommand("SELECT title_id, title, price FROM titles", _connection);
  return _command.BeginExecuteReader (cb, state);
 }

 void EndAsyncOperation(IAsyncResult ar)
 {
  _reader = _command.EndExecuteReader(ar);
 }

 protected void Page_PreRenderComplete(object sender, EventArgs e)
 {
  Output.DataSource = _reader;
  Output.DataBind();
 }

 public override void Dispose()
 {
  if (_connection != null) _connection.Close();
  base.Dispose();
 }
}

 

  AsyncDataBind.aspx.cs 與 AsyncPage.aspx.cs 使用相同的 AddOnPreRenderCompleteAsync 模式。但是,AsyncDataBind.aspx.cs 的 BeginAsyncOperation 方法調(diào)用 ADO.NET 2.0 中的新方法 SqlCommand.BeginExecuteReader(而非 HttpWebRequest.BeginGetResponse),以執(zhí)行一個(gè)異步數(shù)據(jù)庫(kù)查詢(xún)。當(dāng)調(diào)用完成時(shí),EndAsyncOperation 調(diào)用 SqlCommand.EndExecuteReader 以獲取 SqlDataReader,然后將其存儲(chǔ)在私有字段中。在用于 PreRenderComplete 事件(在異步操作完成但呈現(xiàn)該頁(yè)之前引發(fā))的事件處理程序中,AsyncDataBind.aspx.cs 之后將 SqlDataReader 綁定到 Output GridView 控件。從外觀上看,該頁(yè)類(lèi)似于使用 GridView 呈現(xiàn)數(shù)據(jù)庫(kù)查詢(xún)結(jié)果的普通(同步)頁(yè)。但是在內(nèi)部,該頁(yè)更具可伸縮性,因?yàn)樗⒉粧炱鹁€(xiàn)程池線(xiàn)程以等待查詢(xún)返回。

  異步調(diào)用 Web 服務(wù)

  另一個(gè)通常由 ASP.NET Web 頁(yè)執(zhí)行的、與 I/O 相關(guān)的任務(wù)是調(diào)出 Web 服務(wù)。由于 Web 服務(wù)調(diào)用花費(fèi)較長(zhǎng)時(shí)間才能返回,因此,執(zhí)行它們的頁(yè)是用于異步處理的理想選擇。

圖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 顯示生成調(diào)出 Web 服務(wù)的異步頁(yè)的方式。它使用圖 1 和 圖 4 中相同的 AddOnPreRenderCompleteAsync 機(jī)制。該頁(yè)的 Begin 方法通過(guò)調(diào)用 Web 服務(wù)代理的異步 Begin 方法啟動(dòng)一個(gè)異步 Web 服務(wù)調(diào)用。該頁(yè)的 End 方法在私有字段中緩存對(duì) Web 方法返回的 DataSet 的引用,并且 PreRenderComplete 處理程序?qū)?DataSet 綁定到 GridView。作為參考,該調(diào)用的目標(biāo) 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 服務(wù)代理支持兩種對(duì) Web 服務(wù)進(jìn)行異步調(diào)用的機(jī)制。一個(gè)是 .NET Framework 1.x 和 2.0 Web 服務(wù)代理中的每方法 Begin 和 End 方法。另一個(gè)是僅由 .NET Framework 2.0 的 Web 服務(wù)代理提供的新 MethodAsync 方法和 MethodCompleted 事件。

  如果一個(gè) Web 服務(wù)有一個(gè)名為 Foo 的方法,那么除了具有名為 Foo、BeginFoo 和 EndFoo 的方法外,.NET Framework 版本 2.0 Web 服務(wù)代理還包括名為 FooAsync 的方法和名為 FooCompleted 的事件。可以通過(guò)注冊(cè) FooCompleted 事件的處理程序并調(diào)用 FooAsync 來(lái)異步調(diào)用 Foo,如下所示:

proxy.FooCompleted += new FooCompletedEventHandler (OnFooCompleted);
            proxy.FooAsync (...);
            ...
            void OnFooCompleted (Object source, FooCompletedEventArgs e)
            {
            // Called when Foo completes
            }
            

  當(dāng)異步調(diào)用由于 FooAsync 完成而開(kāi)始時(shí),將引發(fā) FooCompleted 事件,從而導(dǎo)致調(diào)用 FooCompleted 事件處理程序。包裝該事件處理程序 (FooCompletedEventHandler) 的委托和傳遞給它的第二個(gè)參數(shù) (FooCompletedEventArgs) 都隨 Web 服務(wù)代理一起生成。可通過(guò) FooCompletedEventArgs.Result 訪(fǎng)問(wèn) Foo 的返回值。

  圖 6 展示使用 MethodAsync 模式異步調(diào)用 Web 服務(wù)的 GetTitles 方法的代碼隱藏類(lèi)。從功能上講,該頁(yè)等同于圖 5 中的頁(yè)。但其內(nèi)部實(shí)現(xiàn)則大為不同。AsyncWSInvoke2.aspx 包括一個(gè) @ Page Async=“true” 指令,類(lèi)似于 AsyncWSInvoke1.aspx。但是,AsyncWSInvoke2.aspx.cs 并不調(diào)用 AddOnPreRenderCompleteAsync;它注冊(cè)一個(gè)用于 GetTitlesCompleted 事件的處理程序,并調(diào)用 Web 服務(wù)代理上的 GetTitlesAsync。ASP.NET 仍然延遲呈現(xiàn)該頁(yè),直到 GetTitlesAsync 完成。在內(nèi)部,當(dāng)異步調(diào)用開(kāi)始以及完成時(shí),它使用 System.Threading.SynchronizationContext 的一個(gè)實(shí)例(2.0 的一個(gè)新類(lèi))接收通知。

圖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 實(shí)現(xiàn)異步頁(yè)有兩個(gè)優(yōu)勢(shì)。首先,MethodAsync 將模擬、區(qū)域性和 HttpContext.Current 注入 MethodCompleted 事件處理程序,而 AddOnPreRenderCompleteAsync 則不然。其次,如果該頁(yè)進(jìn)行多個(gè)異步調(diào)用,而且必須延遲呈現(xiàn)直到所有調(diào)用完成,則使用 AddOnPreRenderCompleteAsync 要求您生成一個(gè)在所有調(diào)用完成前保持無(wú)信號(hào)狀態(tài)的 IasyncResult。使用 MethodAsync,這樣的操作就不是必需的;您只需放置這些調(diào)用(數(shù)量不限),ASP.NET 引擎延遲該呈現(xiàn)階段,直到最后一個(gè)調(diào)用返回。


  異步任務(wù)

  MethodAsync 是從異步頁(yè)進(jìn)行多個(gè)異步 Web 服務(wù)調(diào)用并延遲呈現(xiàn)階段直到所有調(diào)用完成的一個(gè)簡(jiǎn)便方法。但如果您想在一個(gè)異步頁(yè)中執(zhí)行若干異步 I/O 操作,而且這些操作不涉及 Web 服務(wù),那該如何呢? 這么說(shuō),可以反過(guò)來(lái)生成一個(gè) IAsyncResult,它可以返回到 ASP.NET 以允許它了解最后一個(gè)調(diào)用何時(shí)完成的嗎? 幸運(yùn)的是,答案是否定的。

  在 ASP.NET 2.0 中,System.Web.UI.Page 類(lèi)引入了另一個(gè)方法來(lái)簡(jiǎn)化異步操作: RegisterAsyncTask。RegisterAsyncTask 比 AddOnPreRenderCompleteAsync 具有四個(gè)優(yōu)勢(shì)。首先,除了 Begin 和 End 方法,RegisterAsyncTask 還允許您注冊(cè)當(dāng)異步操作長(zhǎng)時(shí)間無(wú)法完成時(shí)調(diào)用的超時(shí)方法。您可以通過(guò)在該頁(yè)的 @ Page 指令中包含 AsyncTimeout 屬性以聲明性方式設(shè)置超時(shí)。AsyncTimeout="5" 將超時(shí)設(shè)置為 5 秒。第二個(gè)優(yōu)勢(shì)是,您可以在一個(gè)請(qǐng)求中多次調(diào)用 RegisterAsyncTask 來(lái)注冊(cè)若干異步操作。和使用 MethodAsync 一樣,ASP.NET 延遲呈現(xiàn)該頁(yè),直到所有操作完成。第三,您可以使用 RegisterAsyncTask 的第四個(gè)參數(shù)將狀態(tài)傳遞給 Begin 方法。最后,RegisterAsyncTask 將模擬、區(qū)域性和 HttpContext.Current 注入 End 和 Timeout 方法。正如本文前面提到的,使用 AddOnPreRenderCompleteAsync 注冊(cè)的 End 方法的情況則不然。

  在其他方面,依賴(lài)于 RegisterAsyncTask 的異步頁(yè)與依賴(lài)于 AddOnPreRenderCompleteAsync 的異步頁(yè)相類(lèi)似。它仍然需要 @ Page 指令(或等效的編程指令,它會(huì)將該頁(yè)的 AsyncMode 屬性設(shè)置為 true)中的 Async=“true” 屬性,而且它仍然與平時(shí)一樣通過(guò) PreRender 事件執(zhí)行,此時(shí)調(diào)用使用 RegisterAsyncTask 注冊(cè)的 Begin 方法,而且進(jìn)一步保持請(qǐng)求處理直到最后一個(gè)操作完成。例如,圖 7 中的代碼隱藏類(lèi)在功能上與圖 1 中的等效,但是它使用 RegisterTaskAsync 而非使用 AddOnPreRenderCompleteAsync。請(qǐng)注意名為 TimeoutAsyncOperation 的超時(shí)處理程序,如果 HttpWebRequest.BeginGetRequest 長(zhǎng)時(shí)間無(wú)法完成,將調(diào)用該處理程序。相應(yīng)的 .aspx 文件包括一個(gè)將超時(shí)間隔設(shè)置為 5 秒的 AsyncTimeout 屬性。還請(qǐng)注意傳給 RegisterAsyncTask 的第四個(gè)參數(shù)(可用于將數(shù)據(jù)傳送到 Begin 方法)的 null。

圖7

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public partial class AsyncPageTask : System.Web.UI.Page
{
 private WebRequest _request;

 protected void Page_Load(object sender, EventArgs e)
 {
  PageAsyncTask task = new PageAsyncTask(
   new BeginEventHandler(BeginAsyncOperation),
   new EndEventHandler(EndAsyncOperation),
   new EndEventHandler(TimeoutAsyncOperation),
  null
 );
 RegisterAsyncTask(task);
 }

 IAsyncResult BeginAsyncOperation(object sender, EventArgs e,
AsyncCallback cb, object state)
 {
  _request = WebRequest.Create("http://msdn.microsoft.com");
  return _request.BeginGetResponse(cb, state);
 }

 void EndAsyncOperation(IAsyncResult ar)
 {
  string text;
  using (WebResponse response = _request.EndGetResponse(ar))
  {
   using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
     text = reader.ReadToEnd();
    }
  }

  Regex regex = new Regex("href\\s*=\\s*\"([^\"]*)\"", RegexOptions.IgnoreCase);
  MatchCollection matches = regex.Matches(text);

  StringBuilder builder = new StringBuilder(1024);
  foreach (Match match in matches)
  {
   builder.Append(match.Groups[1]);
   builder.Append("<br/>");
  }

  Output.Text = builder.ToString();
 }

 void TimeoutAsyncOperation(IAsyncResult ar)
 {
  Output.Text = "Data temporarily unavailable";
 }
}


  RegisterAsyncTask 的主要優(yōu)勢(shì)在于,它允許異步頁(yè)引發(fā)多個(gè)異步調(diào)用,并延遲呈現(xiàn)直到所有調(diào)用完成。它也很好地適用于單個(gè)異步調(diào)用,而且它提供了 AddOnPreRenderCompleteAsync 不具有的超時(shí)選項(xiàng)。如果生成一個(gè)只進(jìn)行一個(gè)異步調(diào)用的異步頁(yè),您可以使用 AddOnPreRenderCompleteAsync 或 RegisterAsyncTask。但對(duì)于放置兩個(gè)以上異步調(diào)用的異步頁(yè),RegisterAsyncTask 極大地簡(jiǎn)化了您的操作。

  由于超時(shí)值是每頁(yè)而非每調(diào)用設(shè)置,因此您可能想知道是否能改變單個(gè)調(diào)用的超時(shí)值。簡(jiǎn)單的回答是否。您可以通過(guò)以編程方式修改頁(yè)的 AsyncTimeout 屬性,逐個(gè)請(qǐng)求地更改超時(shí),但是您無(wú)法將不同超時(shí)分配給從同一請(qǐng)求初始化的不同調(diào)用。
包裝它

  現(xiàn)在,您已經(jīng)了解了 ASP.NET 2.0 中異步頁(yè)的實(shí)質(zhì)。它們?cè)诩磳⑼瞥龅?ASP.NET 版本中非常易于實(shí)現(xiàn),并且其體系結(jié)構(gòu)允許您在一個(gè)請(qǐng)求中批處理多個(gè)異步 I/O 操作,并延遲該頁(yè)的呈現(xiàn)直到所有操作完成。通過(guò)與異步 ADO.NET 和 .NET Framework 中的其他新異步功能相結(jié)合,異步 ASP.NET 頁(yè)針對(duì)因充滿(mǎn)線(xiàn)程池而限制可伸縮性的 I/O 綁定請(qǐng)求問(wèn)題提供了解決方案。

  當(dāng)生成異步頁(yè)時(shí)最后需要注意的一點(diǎn)是,不應(yīng)該啟動(dòng)來(lái)自 ASP.NET 使用的同一線(xiàn)程池的異步操作。例如,在頁(yè)的異步點(diǎn)調(diào)用 ThreadPool.QueueUserWorkItem 會(huì)起反作用,因?yàn)樵摲椒▉?lái)自線(xiàn)程池,從而導(dǎo)致純粹獲取用于處理請(qǐng)求的零線(xiàn)程。相反,調(diào)用內(nèi)置于 Framework 中的異步方法(例如,方法 HttpWebRequest.BeginGetResponse 和 SqlCommand.BeginExecuteReader)通常認(rèn)為是安全的,因?yàn)檫@些方法傾向于使用完成端口實(shí)現(xiàn)異步行為。

posted on 2007-09-18 16:04 獨(dú)孤九劍 閱讀(154) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Learn articles
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久国产精品日日| 亚洲欧美电影院| 久久人体大胆视频| 伊人精品成人久久综合软件| 久久一日本道色综合久久| 欧美制服第一页| 曰韩精品一区二区| 亚洲国产三级网| 久久综合九色99| 亚洲精品在线电影| 99视频超级精品| 国产精品永久免费观看| 老鸭窝毛片一区二区三区| 欧美成人午夜激情| 亚洲一区二区三区四区在线观看| 一本色道久久综合亚洲精品不卡 | 久久久人成影片一区二区三区| 国内精品视频666| 亚洲二区免费| 欧美三日本三级三级在线播放| 香蕉久久国产| 久久婷婷国产麻豆91天堂| 亚洲精品中文字幕在线| 亚洲影院污污.| 亚洲成人自拍视频| 一区二区三区成人| 尤物在线精品| 夜夜嗨av一区二区三区中文字幕| 国产免费亚洲高清| 免费不卡视频| 国产精品女同互慰在线看| 美女视频黄 久久| 国产精品啊啊啊| 欧美成人中文字幕| 国产精品人人做人人爽人人添| 美国成人毛片| 国产精品无码专区在线观看 | 亚洲小视频在线观看| 久久国内精品自在自线400部| 一区二区久久久久久| 久久精品国产77777蜜臀| 亚洲一级一区| 欧美激情亚洲综合一区| 噜噜噜在线观看免费视频日韩| 欧美日韩一区视频| 亚洲风情亚aⅴ在线发布| 国产亚洲综合性久久久影院| 一区二区三区国产在线观看| 亚洲精品永久免费| 老牛国产精品一区的观看方式| 欧美一区二区日韩| 欧美日韩亚洲综合在线| 亚洲黄色毛片| 亚洲国产美女| 久久久久久欧美| 久久免费视频这里只有精品| 国产精品欧美一区二区三区奶水| 亚洲欧洲综合另类| 亚洲黄一区二区三区| 久久国产精品久久久| 久久精品成人欧美大片古装| 国产精品卡一卡二卡三| av成人激情| 亚洲视频一区二区| 欧美日韩综合一区| 日韩视频一区二区三区| 一本久道综合久久精品| 欧美高清在线一区| 91久久极品少妇xxxxⅹ软件| 亚洲精品一区二区三区在线观看 | 夜夜嗨av色一区二区不卡| 亚洲精品视频在线观看网站| 欧美激情第六页| 亚洲黄色大片| 亚洲调教视频在线观看| 欧美视频国产精品| 亚洲一区激情| 久久精品一区二区三区中文字幕| 国产日韩欧美自拍| 久久久国产成人精品| 免费亚洲电影在线| 亚洲精品一区二区三区四区高清 | 国产精品无码专区在线观看| 性欧美在线看片a免费观看| 久久精品国产精品亚洲精品| 韩国av一区二区| 毛片av中文字幕一区二区| 亚洲国产高清在线观看视频| 亚洲午夜av在线| 国产精品一区一区| 久久久五月婷婷| 亚洲精品久久久久久久久久久久| 亚洲调教视频在线观看| 国产一区二区三区久久久| 久久夜色精品国产噜噜av| 亚洲激情电影在线| 亚洲综合成人婷婷小说| 国产亚洲欧美日韩美女| 欧美不卡高清| 亚洲尤物影院| 亚洲高清成人| 久久久蜜桃一区二区人| 亚洲美女区一区| 国产日韩精品电影| 欧美—级在线免费片| 亚洲欧美偷拍卡通变态| 亚洲国产视频直播| 久久久精品欧美丰满| 亚洲免费观看在线观看| 国产亚洲在线观看| 欧美体内she精视频在线观看| 欧美一区二区三区婷婷月色| 91久久精品国产91久久| 久久久久久亚洲精品杨幂换脸| 亚洲精品午夜| 亚洲国产精品久久久久秋霞蜜臀 | 麻豆成人精品| 亚洲欧美激情一区| 亚洲国产日韩欧美在线99| 久久精品一级爱片| 亚洲午夜精品一区二区| 亚洲激情不卡| 国产一区二区三区av电影| 欧美三级精品| 欧美精品久久久久久| 久久精品中文字幕免费mv| 亚洲一级黄色片| 99re6这里只有精品视频在线观看| 噜噜爱69成人精品| 久久精品国产亚洲一区二区三区| 一区二区三区欧美激情| 亚洲韩国青草视频| 伊人天天综合| 激情自拍一区| 国户精品久久久久久久久久久不卡 | 欧美v日韩v国产v| 久久久久成人精品| 久久福利毛片| 欧美在线视频观看免费网站| 亚洲欧美日韩一区二区在线 | 国产综合视频| 国产一区二区久久| 国产精品免费观看在线| 国产精品家庭影院| 国产精品久久久久aaaa| 欧美午夜精品理论片a级按摩| 欧美喷潮久久久xxxxx| 欧美激情综合色| 欧美日韩p片| 欧美日韩中文字幕在线视频| 欧美日韩人人澡狠狠躁视频| 欧美日韩精品免费在线观看视频| 欧美激情久久久久久| 欧美国产一区视频在线观看| 欧美精品色一区二区三区| 欧美日韩国产一区精品一区| 欧美日本韩国一区| 欧美视频日韩视频| 国产精品人人做人人爽 | 蜜臀av在线播放一区二区三区| 久久久国产精品一区二区中文| 久久久精品性| 欧美激情1区| 欧美午夜精品伦理| 国产欧美一区二区精品性| 国产在线精品一区二区中文| 在线精品福利| 一本色道久久综合狠狠躁的推荐| 亚洲一区二区三区精品在线观看 | 亚洲精选91| 午夜久久影院| 美日韩精品免费| 日韩午夜在线电影| 性欧美videos另类喷潮| 裸体一区二区三区| 欧美视频在线观看视频极品| 国产一区二区三区高清| 亚洲美女在线看| 午夜免费电影一区在线观看| 麻豆av一区二区三区| 亚洲免费电影在线| 久久国产精品亚洲va麻豆| 欧美韩国在线| 国产曰批免费观看久久久| 日韩午夜在线| 开心色5月久久精品| 99伊人成综合| 免费h精品视频在线播放| 国产精品久久久久一区| 亚洲精品1区2区| 欧美一区二区三区免费观看视频 | 欧美一级在线视频| 亚洲电影免费观看高清| 午夜日韩av| 欧美日韩国产综合在线| 尤物精品在线| 久久精品人人爽| 国产精品99久久久久久久女警| 久久青草欧美一区二区三区| 国产精品揄拍500视频|