当前位置:首页 > asp.net中的异步页面

asp.net中的异步页面

点击次数:1262  更新日期:2010-12-31
\n

要想了解asp.net 2.0的异步页的处理过程,先列出页面的生命周期:


\n

1 :Init 事件: 页面初始化 ,初始化设置。


\n

2: LoadViewState方法: 加载视图状态, 填充ViewState属性。


\n

3 :LoadPostData方法: 处理回发数据, 处理传入窗体数据。


\n

4: Load 事件: 加载页面 ,页面控件初始化完成并反映了客户端的数据。


\n

5 :RaisePostDataChangedEvent方法: 回发更改通知 引发更改事件。


\n

6 :RaisePostBackEvent方法: 处理回发事件 ,处理引起回发的客户端事件,并在服务上引发相应时间。


\n

7: PreRender事件: 页面预呈现 。


\n

8 :SaveViewState方法: 保存视图状态, 将ViewState属性保存到字符串中。


\n

9 :Render方法: 呈现页面 。


\n

10: Dispose方法: 处置是否对昂贵资源的引用。


\n

11 :Unload事件: 卸载页面 。


\n

页面处理方式:


\n

1:同步处理;


\n

2:异步处理。


\n

同步请求过程:


\n

1:ASP.NET 收到页面请求时,从线程池中提取一个线程并将请求分配给该线程。


\n

2:页在该请求期间保留线程,防止该线程用于处理其他请求。


\n

3:如果一个同步请求需要运算时间较长,此时分配给该请求的线程在调用返回之前处于挂起状态。


\n

4:等待线程返回后完成页面的其它生命周期。


\n

同步请求的生命周期和线程关系图:


\n



\n

同步请求的问题


\n

线程池的可用线程是有限的,如果此时请求过多,ASP.NET 因 503“Server Unavailable”错误使后续请求失败。这让asp.net能够接收的请求量会大大减少,影响了可伸缩性。


\n

异步的处理过程:


\n

前面的两点和普通同步请求一样,不同的是对于比较费时的过程的处理方式:


\n

1:一个异步操作开始响应 ASP.NET 的信号之后,该线程返回线程池。


\n

2:ASP.NET 调用使用 AddOnPreRenderCompleteAsync 注册的 Begin 方法。Begin 方法的任务是启动诸如数据库查询或 Web 服务调用的异步操作,并立即返回。


\n

3:线程返回到线程池。同时,Begin 方法返回 IAsyncResult。


\n

4: ASP.NET 从线程池提取线程并调用 End 方法。


\n

5:当 End 返回之后,ASP.NET 执行该页生命周期其余的部分。


\n

异步请求的生命周期和线程关系图:


\n

\n

异步的优势:

线程池线程得到了高效的使用,提高了可伸缩性。原来挂起等待的线程现在可用于服务其他请求。


\n

异步加载数据的示例:


\n

第一步:让页面支持异步。设置Async属性。


\n

第二步:因为是操作数据库,想让数据库支持异步,需要对数据库连接串进行配置。


\n

Asynchronous Processing=true。

第三步:在页面的Page_Load事件中注册异步事件。


\n
<!–

\n

Code highlighting produced by Actipro CodeHighlighter (freeware)
\nhttp://www.CodeHighlighter.com/

\n

–>protected void Page_Load(object sender, EventArgs e)
{
AddOnPreRenderCompleteAsync(
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler(EndAsyncOperation)
);
}
IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
{
string sql = “SELECT TOP 10 * FROM dbo.Card_Ext”;

\n

SqlConnection _conn = new SqlConnection(ConfigurationManager.


\n

AppSettings["DataAccessContionStringRead"].ToString());

_conn.Open();
SqlCommand cmd = new SqlCommand(sql, _conn);

\n

IAsyncResult rIsynResult = cmd.BeginExecuteReader(cb, cmd,


\n

CommandBehavior.CloseConnection);

return rIsynResult;
}
void EndAsyncOperation(IAsyncResult IResult)
{
if (!IResult.IsCompleted)
{
IResult.AsyncWaitHandle.WaitOne();
}
else
{
SqlDataReader dr = (IResult.AsyncState as SqlCommand).EndExecuteReader(IResult);
if (!dr.IsClosed)
{
List<string> _list = new List<string>();
while (dr.Read())
{
_list.Add(dr[0].ToString());
}
this.GridView1.DataSource = _list;
this.GridView1.DataBind();
}
dr.Close();
}
}

\n