体验ASP.NET 2.0 中的异步页功能

asp.net|异步

(一).简单介绍实现原理

  下图左为未使用异步页功能执行过程(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. 后台异步页面相关代码 :

1private WebRequest _request;
2 protected void Page_Load(object sender, EventArgs e)
3 {
4 //注册异步调用的Begin和End方法.
5 AddOnPreRenderCompleteAsync(
6 new BeginEventHandler(BeginAsyncOperation),
7 new EndEventHandler(EndAsyncOperation)
8 );
9 }
10
11 //异步调用开始方法(当执行此方法时,当前线程就回到线程池,等待为其它请求服务).
12 IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
13 {
14 _request = WebRequest.Create("http://blog.csdn.net/chengking/");
15 return _request.BeginGetResponse(cb, state);
16 }
17
18 //异步调用结束后的接收方法(异步操作执行完成后,会重新从线程池中取个线程为本页面请求服务).
19 void EndAsyncOperation(IAsyncResult ar)
20 {
21 string text;
22 using (WebResponse response = _request.EndGetResponse(ar))
23 {
24 using (StreamReader reader = new StreamReader(response.GetResponseStream()))
25 {
26 text = reader.ReadToEnd();
27 }
28 }
29 this.lbOupput.Text = text;
30 }
  2. 数据库对象SqlCommand实现异步调用功能.

  a. Page标志加属性: Async="true", 添加后代码如下:

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="AsyncPage.aspx.cs"
Inherits="_Default" Async="true" %>
  b. 后台代码

1public partial class AsyncVisitDatabase : System.Web.UI.Page
2{
3 //定义数据操作对象
4 private SqlConnection _connection;
5 private SqlCommand _command;
6 private SqlDataReader _reader;
7
8 protected void Page_Load(object sender, EventArgs e)
9 {
10 if (!IsPostBack)
11 {
12 //注册事件Page_PreRender执行完成时执行方法
13 this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
14
15 /**////注册异步调用的Begin和End方法.
16 AddOnPreRenderCompleteAsync(
17 new BeginEventHandler(BeginAsyncOperation),
18 new EndEventHandler(EndAsyncOperation)
19 );
20 }
21 }
22
23 //异步调用开始方法(当执行此方法时,当前线程就回到线程池,等待为其它请求服务).
24 IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
25 {
26 string connect = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
27 _connection = new SqlConnection(connect);
28 _connection.Open();
29 _command = new SqlCommand("select * from sales", _connection);
30 return _command.BeginExecuteReader(cb, state);
31 }
32
33 //异步调用结束后的接收方法(异步操作执行完成后,会重新从线程池中取个线程为本页面请求服务).
34 void EndAsyncOperation(IAsyncResult ar)
35 {
36 _reader = _command.EndExecuteReader(ar);
37 }
38
39 //事件Page_PreRender执行完成时执行方法,在这里可以将异步调用返回结果赋值给页面上的控件或者其它善后操作.
40 protected void Page_PreRenderComplete(object sender, EventArgs e)
41 {
42 GridView1.DataSource = _reader;
43 GridView1.DataBind();
44 }
45
46 public override void Dispose()
47 {
48 if (_connection != null)
49 _connection.Close();
50 base.Dispose();
51 }
52}
  3. 实现异步调用Webservice

  a. Page标志加属性: Async="true", 添加后代码如下:
 
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="AsyncPage.aspx.cs"
Inherits="_Default" Async="true" %>
  b.后台代码

  Webservice方法(生成数据).

1public class WebService : System.Web.Services.WebService {
2
3 public WebService () {
4
5 //Uncomment the following line if using designed components
6 //InitializeComponent();
7 }
8
9 [WebMethod]
10 public DataSet GetData() {
11 return CreateData();
12 }
13
14 private DataSet CreateData()
15 {
16 DataTable dtTypeChild = new DataTable();
17 dtTypeChild.Columns.Add(new DataColumn("TypeID", typeof(int)));
18 dtTypeChild.Columns.Add(new DataColumn("TypeDetail", typeof(string)));
19 //Add data
20 DataRow drChild1 = dtTypeChild.NewRow();
21 drChild1["TypeID"] = 1;
22 drChild1["TypeDetail"] = "Apple";
23 dtTypeChild.Rows.Add(drChild1);
24 DataRow drChild2 = dtTypeChild.NewRow();
25 drChild2["TypeID"] = 2;
26 drChild2["TypeDetail"] = "orange";
27 dtTypeChild.Rows.Add(drChild2);
28 DataRow drChild3 = dtTypeChild.NewRow();
29 drChild3["TypeID"] = 3;
30 drChild3["TypeDetail"] = "banana";
31 dtTypeChild.Rows.Add(drChild3);
32 DataRow drChild4 = dtTypeChild.NewRow();
33 drChild4["TypeID"] = 4;
34 drChild4["TypeDetail"] = "pineapple";
35 dtTypeChild.Rows.Add(drChild4);
36 DataRow drChild5 = dtTypeChild.NewRow();
37 drChild5["TypeID"] = 5;
38 drChild5["TypeDetail"] = "pear";
39 dtTypeChild.Rows.Add(drChild5);
40 dtTypeChild.TableName = "fruit";
41
42 DataSet ds = new DataSet();
43 ds.Tables.Add(dtTypeChild);
44 return ds;
45 }
46
47}
  后台代码:

1public partial class AsyncVisitWebservice : System.Web.UI.Page
2{
3 private King.WebService _ws;
4 private DataSet _ds;
5
6 protected void Page_Load(object sender, EventArgs e)
7 {
8 if (!IsPostBack)
9 {
10 this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);
11 _ws = new King.WebService();
12 _ws.GetDataCompleted += new King.GetDataCompletedEventHandler(GetDataCompleted);
13 _ws.Url = new Uri(Request.Url, "WebService.asmx").ToString();
14 _ws.UseDefaultCredentials = true;
15 _ws.GetDataAsync();
16 }
17 }
18
19 void GetDataCompleted(Object source, King.GetDataCompletedEventArgs e)
20 {
21 _ds = e.Result;
22 }
23
24 protected void Page_PreRenderComplete(object sender, EventArgs e)
25 {
26 this.GridView1.DataSource = _ds;
27 GridView1.DataBind();
28 }
29
30 public override void Dispose()
31 {
32 if (_ws != null)
33 _ws.Dispose();
34 base.Dispose();
35 }
36}
  4. 用 PageAsyncTask 实现异步调用功能(除了实现异步功能,还可以实现异步操作等待时间以及时间超时操作)

  a. Page标志加属性: Async="true" AsyncTimeout="5" , 添加后代码如下:

1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AsyncPageTask.aspx.cs" Inherits="AsyncPageTask" Async="true" AsyncTimeout="5" %>

  b. 后台代码

1public partial class AsyncPageTask : System.Web.UI.Page
2{
3 private WebRequest _request;
4
5 protected void Page_Load(object sender, EventArgs e)
6 {
7 PageAsyncTask task = new PageAsyncTask(
8 new BeginEventHandler(BeginAsyncOperation),
9 new EndEventHandler(EndAsyncOperation),
10 new EndEventHandler(TimeoutAsyncOperation),
11 null
12 );
13
14 RegisterAsyncTask(task);
15 }
16
17 IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
18 {
19 _request = WebRequest.Create("http://blog.csdn.net/chengking");
20 return _request.BeginGetResponse(cb, state);
21 }
22
23 void EndAsyncOperation(IAsyncResult ar)
24 {
25 string text;
26 using (WebResponse response = _request.EndGetResponse(ar))
27 {
28 using (StreamReader reader = new StreamReader(response.GetResponseStream()))
29 {
30 text = reader.ReadToEnd();
31 }
32 }
33
34 lbDisplay.Text = text.ToString();
35 }
36
37 //时间超时执行操作
38 void TimeoutAsyncOperation(IAsyncResult ar)
39 {
40 lbDisplay.Text = "Failture!";
41 }
42}
  (三).遗留问题.

  第二种方式: 数据库对象SqlCommand实现异步调用功能

  (对应示例代码中的页面: AsyncVisitDatabase.aspx),示例代码我始终没有调试成功!

  数据库里有数据,但显示不到GridView中去.

  如哪位能调试通过,敬请指点!!!

时间: 2024-11-01 08:21:09

体验ASP.NET 2.0 中的异步页功能的相关文章

ASP.NET 2.0 中的异步页功能应用

asp.net|异步 下载本文源代码:WickedCode0510.exe ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个远程 Web 服务或查询一个远程数据库,并等待调用

ASP.NET 2.0中的异步页功能应用

ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员 和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原 因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配 给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程 用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个 远程 Web 服务或查询一个远程数据库,并等待调用返回),那么分配给该请求 的线程在调用返回之前处于挂起状态.这影响

ASP.NET 2.0 中的异步页[来自MSDN]

ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个远程 Web 服务或查询一个远程数据库,并等待调用返回),那么分配给该请求的线程在调用返回之前处于挂起状态.这影响了可伸缩性,

ASP.NET 2.0 中改进的缓存功能

asp.net|缓存 Stephen Walther      Microsoft Corporation      适用于:      Microsoft ASP.NET 2.0      Microsoft ASP.NET Framework      Microsoft SQL Server      Microsoft Visual Studio .NET      摘要:本文中,Stephen Walther 将重点介绍 ASP.NET 2.0 中新增的缓存功能,以及如何使用这些新功能

体验ASP.NET 2.0 中的数据访问控件

asp.net|访问|控件|数据 简介 数据访问一直是开发 Web 应用程序的一个关键问题.几乎每个商业应用程序都需要数据驱动的 Web 页面.由于数据访问如此普遍,开发人员不断地为简单的数据库任务重新生成复杂的代码就显得毫无意义了.开发人员需要从格式各异的不同数据源中快速访问数据.幸运的是,ASP.NET 2.0 中新增的数据访问控件和 ADO.NET 2.0 解决了这一问题. 对于传统的 ASP 和 ASP.NET 1.1 应用程序而言,开发人员不得不创建代码访问和更新数据库,将检索到的数据

ASP.NET 2.0 中实现跨页提交

在ASP.NET 2.0中,对于跨页提交已经有了非常合理的解决方案下面是一个示例:BeginPage.aspx: 请注意Button1的PostBackUrl属性设置 <%@ Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitio

ASP.NET 2.0 中收集的小功能点

asp.net 1.asp.net 2.0中的MaxPageStateFieldLength 属性 在asp.net 2.0中,可以强制对viewstate进行分段传输了,使用的是Page.MaxPageStateFieldLength 属性,可以设置viewstate中,每个页面状态字段的最大字节数.格式如下,要在WEB.CONFIG文件里设置的:    <pages maxPageStateFieldLength="5" />    其中,将设置把viewstate为不

在asp.net 2.0中结合母板页使用meta标签(扩展@Page指令)

asp.net 介绍母板页是asp.net 2.0中的一个非常强大的特性,但是它却不能提供一个实现最基础的针对搜索引擎优化的方法.如果你想你的web页被搜索引擎收录并提高排名,那么你就需要在每一个页都指定一个title和meta标记.本文将说明如何扩展你的asp.net页,以使得在使用母板页的时候你可以直接在你内容页的@Page指令中指定你的meta标签的描述和meta标签的关键字 背景当你要针对搜索引擎优化你的web页的时候,设置页的title标签和页的meta描述是其中最重要的因素之一.<t

ASP.NET 2.0 中收集的小功能点(转)_实用技巧

1.asp.net 2.0中的MaxPageStateFieldLength 属性 在asp.net 2.0中,可以强制对viewstate进行分段传输了,使用的是Page.MaxPageStateFieldLength 属性,可以设置viewstate中,每个页面状态字段的最大字节数.格式如下,要在WEB.CONFIG文件里设置的:<pages maxPageStateFieldLength="5" />其中,将设置把viewstate为不超过5字节,如果实际的views