天天看點

asp.net 2.0異步操作頁面asp.net 2.0異步操作頁面

asp.net 2.0異步操作頁面

(一).簡單介紹實作原理

  下圖左為未使用異步頁功能執行過程(Asp.net 1.0通常情況), 下圖右為使用了異步頁執行過程(Asp.net 2.0新增特性).

(Asp.net 1.0一般處理過程) (使用Asp.net 2.0新增特性異步頁功能處理過程) 

  從左圖中看出,在一個頁面整個請求的過程中, 一個線程始終為同一個頁面的請求服務.

  而從右圖可以看出,在一個頁面請求的過程中, 可以由不同的線程為本頁面請求服務.

  顯然,采用圖中方式在用戶端請求數量多時,網站整體效率較高. 因為:

  1. 當未使用異步頁時,一個線程隻能為同一個頁面的請求服務. 即使頁面請求過程中處理其它的I/O等操作時,此線程也一直處于等待狀态. 當此頁面使用完此線程時,才将它放回到線程池. 線程數量是有限的! 是以當不使用線程時及時放回線池可以使系統性能大大提高!

  2.當使用了異步頁功能時,如右圖中,開始Thread1是為頁面服務的,但當頁面處理其它的事情(比如I/O或調用其它 WebService) 時,Thread1被放回線程池, 此時Thread1可以為其它頁面請求服務了. 當此頁面執行完自己的操作回來後, Thread2接着為頁面請求服務,并不是使用的原來的線程Thread1. 這樣網站的伸縮性會更好.

 (二).使用方法示例

 I. 用 Page.AddOnPreRenderCompleteAsync 實作異步頁功能

  a. Page标志加屬性: Async="true", 添加後代碼如下:

<%@ Page Language="C#" AutoEventWireup="true"

CodeFile="AsyncPage.aspx.cs"

Inherits="_Default" Async="true" %> 

  b. 背景異步頁面相關代碼 :

private WebRequest _request;

protected void Page_Load(object sender, EventArgs e)

 ...{

 //注冊異步調用的Begin和End方法.

 AddOnPreRenderCompleteAsync(

 new BeginEventHandler(BeginAsyncOperation),

 new EndEventHandler(EndAsyncOperation)

 );

 }

 //異步調用開始方法(當執行此方法時,目前線程就回到線程池,等待為其它請求服務).

 IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)

 ...{

 _request = WebRequest.Create("http://blog.csdn.net/chengking/");

 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();

 }

}

 this.lbOupput.Text = text;

}

2. 資料庫對象SqlCommand實作異步調用功能.

  a. Page标志加屬性: Async="true", 添加後代碼如下:

<%@ Page Language="C#" AutoEventWireup="true"

CodeFile="AsyncPage.aspx.cs"

Inherits="_Default" Async="true" %> 

  b. 背景代碼

public partial class AsyncVisitDatabase : System.Web.UI.Page

...{

 //定義資料操作對象

 private SqlConnection _connection;

 private SqlCommand _command;

 private SqlDataReader _reader;

 protected void Page_Load(object sender, EventArgs e)

 ...{

 if (!IsPostBack)

 ...{

 //注冊事件Page_PreRender執行完成時執行方法

 this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);

            /**注冊異步調用的Begin和End方法.

            AddOnPreRenderCompleteAsync(

            new BeginEventHandler(BeginAsyncOperation), new EndEventHandler(EndAsyncOperation));

        }

    }

//異步調用開始方法(當執行此方法時,目前線程就回到線程池,等待為其它請求服務).

 IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)

 ...{

 //_request = WebRequest.Create("http://blog.csdn.net/chengking/");

 //return _request.BeginGetResponse(cb, state);

     string connect = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

 _connection = new SqlConnection(connect);

 _connection.Open();

 _command = new SqlCommand("select * from gsjbxx", _connection);

return _command.BeginExecuteReader(cb, state);

 }

 //異步調用結束後的接收方法(異步操作執行完成後,會重新從線程池中取個線程為本頁面請求服務).

 void EndAsyncOperation(IAsyncResult ar)

 ...{

     _reader = _command.EndExecuteReader(ar);

//為了確定我得到了相應的資料并可以顯示在DATAVIEW中

     table.Load(_reader);

 }

 protected void Page_PreRenderComplete(object sender, EventArgs e)

 ...{

    this.GridView1.DataSource = table;

     this.GridView1.DataBind();

 }