asp.net|重新整理|頁面|非同步
ASP.NET 2.0的非同步頁面重新整理功能真得很酷,今天嘗試用它解決我的一個應用問題,真是幫了大忙了。
我的頁面要向背景socket服務提交一個查詢,首先這是一個可能長時間不返回的操作;其次為了拿到socket服務返回的長度不定、有可能很大的Response資料,我不得不採用了dotNET的IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state);辦法來非同步提交socket命令,然後在回呼函數中迭代調用int EndReceive(IAsyncResult asyncResult);來擷取Response資料直到資料被取完,這一系列的資料片斷都緩衝在一個MemoryBlock鏈表中。
這種情況下,ASP.NET頁面要想用表格展示Response資料,必須能夠被非同步重新整理。
ASP.NET 1.x 本質上不支援非同步頁,但是通過堅韌的努力和不懈地創新可以產生非同步頁。有關更多概述資訊,請參閱 MSDN®Magazine 2003 年 6 月刊的文章“Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code”,該文章的作者是 Fritz Onion。
但ASP.NET 2.0 極大地簡化了產生非同步頁的方式。首先使用該頁的 @ Page 指令引入 Async=“true” 屬性。
其次,在 Page_Load 時,註冊事件Page_PreRender:
private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
// 註冊事件Page_PreRender執行完成時執行方法
// Hook PreRenderComplete event for data binding
this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
接下來,我在點擊按鈕的事件函數中,開始我的非同步作業之旅:
/// PageAsyncTask 的方式則是增強版本,除了非同步頁面處理開始和結束方法自身外,
/// 還可以提供在逾時情況下的處理方法,以及處理時的狀態物件。
///
PageAsyncTask task = new PageAsyncTask(
new BeginEventHandler(BeginSubmitKeywordsAsyncOperation),
new EndEventHandler(EndSubmitKeywordsAsyncOperation),
new EndEventHandler(TimeoutSubmitKeywordsAsyncOperation),
null
);
RegisterAsyncTask(task);
/// 對大多數簡單的非同步處理情況,可以直接調用AddOnPreRenderCompleteAsync 方法,
/// 提交頁面請求開始和結束時的處理代碼
//AddOnPreRenderCompleteAsync(
// new BeginEventHandler(BeginSubmitKeywordsAsyncOperation),
// new EndEventHandler(EndSubmitKeywordsAsyncOperation)
//);
該頁經曆其常規處理生命週期,直到 PreRender 事件剛剛引發之後。然後,ASP.NET 調用使用 RegisterAsyncTask註冊的 Begin 方法BeginSubmitKeywordsAsyncOperation。這個方法中我將向sokcet服務提交我的命令,然後將socket.BeginReceive方法得到的IasyncResult對象返回給ASP.NET。
然後,我的socket非同步回呼函數在最終全部獲得資料流後,通過調用
callback.Invoke(result);
來通知頁面socket這邊已經完成工作了。
於是ASP.NET喚起EndSubmitKeywordsAsyncOperation方法:
/// <summary>
/// 非同步呼叫結束後的接收方法(非同步作業執行完成後,會重新從線程池中取個線程為本頁面請求服務).
/// </summary>
/// <param name="ar"></param>
void EndSubmitKeywordsAsyncOperation(IAsyncResult ar)
{
_resultDataset = _submit.getResultDataset(ar);
在這個函數中,我就可以拿到資料流了。
之後,ASP.NET又喚起Page_PreRender事件,從而可以在這個事件中,把頁面上的表格正確填充了。
這樣,就達到了我的目的。而且向後台提交後等待被再度啟用逾時了,也可以由
void TimeoutSubmitKeywordsAsyncOperation(IAsyncResult ar)
來做合適的處理。
參考資源:
1:
ASP.NET 2.0 中的非同步頁
http://www.microsoft.com/china/msdn/library/webservices/asp.net/issuesWickedCodetoc.mspx?mfr=true
發布日期: 2006-4-19 | 更新日期: 2006-4-19
2: