程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> ASP.NET 2.0中的異步頁功能應用

ASP.NET 2.0中的異步頁功能應用

編輯:關於ASP.NET

ASP.NET 2.0 提供了大量新功能,其中包括聲明性數據綁定和母版頁,成員 和角色管理服務等。但我認為最棒的功能是異步頁,接下來讓我告訴您其中的原 因。

當 ASP.NET 接收針對頁的請求時,它從線程池中提取一個線程並將請求分配 給該線程。一個普通的(或同步的)頁在該請求期間保留線程,從而防止該線程 用於處理其他請求。如果一個同步請求成為 I/O 綁定(例如,如果它調用一個 遠程 Web 服務或查詢一個遠程數據庫,並等待調用返回),那麼分配給該請求 的線程在調用返回之前處於掛起狀態。這影響了可伸縮性,原因是線程池的可用 線程是有限的。如果所有請求處理線程全部阻塞以等待 I/O 操作完成,則其他 請求排入隊列等待線程釋放。最好的情況是吞吐量減少,因為請求等待較長的時 間才能得到處理。最壞的情況則是該隊列填滿,並且 ASP.NET 因 503“Server Unavailable”錯誤使後續請求失敗。

異步頁為由 I/O 綁定的請求引起的問題提供優秀的解決方案。頁處理從線程 池線程開始,但是當一個異步 I/O 操作開始響應 ASP.NET 的信號之後,該線程 返回線程池。當該操作完成時,ASP.NET 從線程池提取另一個線程,並完成該請 求的處理。由於線程池線程得到了更高效的使用,因此提高了可伸縮性。那些掛 起等待 I/O 完成的線程現在可用於服務其他請求。直接的受益方是不執行長時 間 I/O 操作並因此可以快速進出管線的請求。長時間等待進入管線會對此類請 求的性能帶來不小的負面影響。

ASP.NET 2.0 Beta 2 異步頁基礎結構的相關文檔很少。讓我們展望一下異步 頁的前景,從而彌補這點不足。請記住,本專欄涉及 ASP.NET 2.0 和 .NET Framework 2.0 的測試版本。

ASP.NET 1.x 中的異步頁

ASP.NET 1.x 本質上不支持異步頁,但是通過堅韌的努力和不懈地創新可以 生成異步頁。有關更多概述信息,請參閱相關資料

這裡的技巧是,在一個頁的代碼隱藏類中實現 IhttpAsyncHandler,從而提 示 ASP.NET 通過調用 IHttpAsyncHandler.BeginProcessRequest 來處理請求, 而不是通過調用該頁的 IHttpHandler.ProcessRequest 方法。然後,您的 BeginProcessRequest 實現可以啟動另一個線程。該線程調用 base.ProcessRequest,使得頁進入其常規請求處理生命周期(完成諸如 Load 和 Render 的事件),但是在非 ThreadPool 線程上例外。同時,啟動新線程之 後 BeginProcessRequest 立即返回,從而允許執行 BeginProcessRequest 的線 程返回線程池。

這是基本思想,但細節中還有很多注意事項。其中,您需要實現 IAsyncResult,並從 BeginProcessRequest 中返回它。這通常意味著創建一個 ManualResetEvent 對象,並且當 ProcessRequest 在後台線程中返回時向其發 送信號。此外,您必須提供調用 base.ProcessRequest 的線程。遺憾的是,多 數用於將工作移到後台線程的常規技術(包括 Thread.Start、 ThreadPool.QueueUserWorkItem 和異步委托)在 ASP.NET 應用程序中都是起反 作用的,因為它們或者從線程池“偷盜”線程,或者有不受限制的線程增長的危 險。正確的異步頁實現使用自定義線程池,但自定義線程池類不容易編寫。

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

ASP.NET 2.0 中的異步頁

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

在後台,這會通知 ASP.NET 在該頁中實現 IhttpAsyncHandler。接下來,您 在該頁生存期的早期(例如,在 Page_Load 時)調用新的 Page.AddOnPreRenderCompleteAsync 方法來注冊一個 Begin 方法和一個 End 方法,如以下代碼所示:

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved