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", 添加后代码如下:
CodeFile="AsyncPage.aspx.cs"
Inherits="_Default"Async="true"%>
b. 后台异步页面相关代码 :
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1privateWebRequest_request;
2protectedvoidPage_Load(objectsender,EventArgse)
3{
4//注册异步调用的Begin和End方法.
5AddOnPreRenderCompleteAsync(
6newBeginEventHandler(BeginAsyncOperation),
7newEndEventHandler(EndAsyncOperation)
8);
9}
10
11//异步调用开始方法(当执行此方法时,当前线程就回到线程池,等待为其它请求服务).
12IAsyncResultBeginAsyncOperation(objectsender,EventArgse,AsyncCallbackcb,objectstate)
13{
14_request=WebRequest.Create("http://blog.csdn.net/chengking/");
15return_request.BeginGetResponse(cb,state);
16}
17
18//异步调用结束后的接收方法(异步操作执行完成后,会重新从线程池中取个线程为本页面请求服务).
19voidEndAsyncOperation(IAsyncResultar)
20{
21stringtext;
22using(WebResponseresponse=_request.EndGetResponse(ar))
23{
24using(StreamReaderreader=newStreamReader(response.GetResponseStream()))
25{
26text=reader.ReadToEnd();
27}
28}
29this.lbOupput.Text=text;
30}
2.数据库对象SqlCommand实现异步调用功能.
a. Page标志加属性: Async="true", 添加后代码如下:
CodeFile="AsyncPage.aspx.cs"
Inherits="_Default"Async="true"%>
b. 后台代码
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1publicpartialclassAsyncVisitDatabase:System.Web.UI.Page
2{
3//定义数据操作对象
4privateSqlConnection_connection;
5privateSqlCommand_command;
6privateSqlDataReader_reader;
7
8protectedvoidPage_Load(objectsender,EventArgse)
9{
10if(!IsPostBack)
11{
12//注册事件Page_PreRender执行完成时执行方法
13this.PreRenderComplete+=newEventHandler(Page_PreRenderComplete);
14
15/**////注册异步调用的Begin和End方法.
16AddOnPreRenderCompleteAsync(
17newBeginEventHandler(BeginAsyncOperation),
18newEndEventHandler(EndAsyncOperation)
19);
20}
21}
22
23//异步调用开始方法(当执行此方法时,当前线程就回到线程池,等待为其它请求服务).
24IAsyncResultBeginAsyncOperation(objectsender,EventArgse,AsyncCallbackcb,objectstate)
25{
26stringconnect=WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
27_connection=newSqlConnection(connect);
28_connection.Open();
29_command=newSqlCommand("select*fromsales",_connection);
30return_command.BeginExecuteReader(cb,state);
31}
32
33//异步调用结束后的接收方法(异步操作执行完成后,会重新从线程池中取个线程为本页面请求服务).
34voidEndAsyncOperation(IAsyncResultar)
35{
36_reader=_command.EndExecuteReader(ar);
37}
38
39//事件Page_PreRender执行完成时执行方法,在这里可以将异步调用返回结果赋值给页面上的控件或者其它善后操作.
40protectedvoidPage_PreRenderComplete(objectsender,EventArgse)
41{
42GridView1.DataSource=_reader;
43GridView1.DataBind();
44}
45
46publicoverridevoidDispose()
47{
48if(_connection!=null)
49_connection.Close();
50base.Dispose();
51}
52}
3.实现异步调用Webservice
a. Page标志加属性: Async="true", 添加后代码如下:
CodeFile="AsyncPage.aspx.cs"
Inherits="_Default"Async="true"%>
b.后台代码
Webservice方法(生成数据).
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1publicclassWebService:System.Web.Services.WebService{
2
3publicWebService(){
4
5//Uncommentthefollowinglineifusingdesignedcomponents
6//InitializeComponent();
7}
8
9[WebMethod]
10publicDataSetGetData(){
11returnCreateData();
12}
13
14privateDataSetCreateData()
15{
16DataTabledtTypeChild=newDataTable();
17dtTypeChild.Columns.Add(newDataColumn("TypeID",typeof(int)));
18dtTypeChild.Columns.Add(newDataColumn("TypeDetail",typeof(string)));
19//Adddata
20DataRowdrChild1=dtTypeChild.NewRow();
21drChild1["TypeID"]=1;
22drChild1["TypeDetail"]="Apple";
23dtTypeChild.Rows.Add(drChild1);
24DataRowdrChild2=dtTypeChild.NewRow();
25drChild2["TypeID"]=2;
26drChild2["TypeDetail"]="orange";
27dtTypeChild.Rows.Add(drChild2);
28DataRowdrChild3=dtTypeChild.NewRow();
29drChild3["TypeID"]=3;
30drChild3["TypeDetail"]="banana";
31dtTypeChild.Rows.Add(drChild3);
32DataRowdrChild4=dtTypeChild.NewRow();
33drChild4["TypeID"]=4;
34drChild4["TypeDetail"]="pineapple";
35dtTypeChild.Rows.Add(drChild4);
36DataRowdrChild5=dtTypeChild.NewRow();
37drChild5["TypeID"]=5;
38drChild5["TypeDetail"]="pear";
39dtTypeChild.Rows.Add(drChild5);
40dtTypeChild.TableName="fruit";
41
42DataSetds=newDataSet();
43ds.Tables.Add(dtTypeChild);
44returnds;
45}
46
47}
后台代码:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1publicpartialclassAsyncVisitWebservice:System.Web.UI.Page
2{
3privateKing.WebService_ws;
4privateDataSet_ds;
5
6protectedvoidPage_Load(objectsender,EventArgse)
7{
8if(!IsPostBack)
9