实现异步页面的两种用法
来源:互联网 发布:融资租赁业务软件 编辑:程序博客网 时间:2024/05/17 22:53
ASP.NET页面会被HTTP处理程序作为Page类的实例处理。每个请求会占用ASP.NET线程池中的一个线程,在请求完毕后该线程才会被释放。如果被请求的页面频繁地启动外部的、高耗时的任务时,经常会出现ASP.NET进程闲置,但池中没有空闲的线程来处理新入的其他页面的请求。这种情况下,创建异面页面可以减轻这个问题。
异步ASP.NET页面的构建涉及两个方面: @Page指令的一个新属性Async,以及注册若干异步执行的任务。异步任务可以通过两种途径注册:一种是为PreRenderComplete事件定义异步处理程序Begin/End对(AddOnPreRenderCompleteAsync方法用于将异步事件处理程序添加到页面的PreRenderComplete事件中);另一种是创建代表异步任务的PageAsyncTask对象,PageAsyncTask类代表要以异步方式执行任务(RegisterAsyncTask方法能够接受一个PageAsyncTask对象,返回void)。
AddOnPreRenderCompleteAsync和RegisterAsyncTask的区别:
从功能上讲,这两个方法几乎相同,二者都会将请求的执行分为两部分——分别在同步点前后。他们之间的区别在于:第一个区别在逻辑上,RegisterAsyncTask是一个用于在一个页面中运行多个异步任务的API(而不能跨越多个带有Async=true属性的异步页面),而AddOnPreRenderCompleteAsync是专门为多个异步页面设计的。RegisterAsyncTask执行End处理程序时,所处线程的上下文比AddOnPreRenderCompleteAsync所处线程的更丰富。该线程上下文包括模拟(impersonation)和HTTP上下文信息,该信息在一般异步页面的End处理程序所处线程中不存在。此外,RegisterAsyncTask还允许设置超时值,确保任何任务消耗的时间不会超过指定的秒数。另一个区别在:RegisterAsyncTask有利于实现对远程源的多个调用。我们只需设置一个布尔类型的标志,便会获得并行执行的能力,而不必要自行创建并管理自定义的IAsyncResult对象。
异步页面的加载分两个过程完成,第一部分是页面的PreInit 事件到PreRender 事件,第二部分开始执行异步任务,执行完异步任务后执行Page_PreRenderComplete事件,执行完后呈现html给浏览器。
前台代码示例:
View Code <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="StreamDownload.aspx.cs" Inherits="WebTestDemo.AsyncPage.StreamDownload" Async="true" Trace="true"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <%=msdnData%> </div> </form> </body> </html>
注意:以上@Page指令的Async和Trace属性。Async属性使页面能够为PreRenderComplete事件注册异步处理程序,Trace属性使页面能够显示页面跟踪信息。
后台代码示例:
View Code /// <summary> /// 异步下载MSDN首页实例 /// </summary> public partial class StreamDownload : System.Web.UI.Page { const string connectionToMSDN = "http://msdn.microsoft.com"; private WebRequest req; public string msdnData; protected override void OnInit(EventArgs e) { //将跟踪消息写入页面跟踪日志 Trace.Warn("当前线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); } protected void Page_Load(object sender, EventArgs e) { //AddOnPreRenderCompleteAsync方法 AddOnPreRenderCompleteAsync( new BeginEventHandler(BeginTask), new EndEventHandler(EndTask)); //RegisterAsyncTask方法 //PageAsyncTask task = new PageAsyncTask( // new BeginEventHandler(BeginTask), // new EndEventHandler(EndTask), // null, // null); //RegisterAsyncTask(task); } IAsyncResult BeginTask(object sender, EventArgs e, AsyncCallback cb, object state) { Trace.Warn("开始异步 当前线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); //准备一个Web请求 req = WebRequest.Create(connectionToMSDN); //开始操作并返回IAsyncResult对象 return req.BeginGetResponse(cb, state); } void EndTask(IAsyncResult ar) { //这段代码将调用一个池里的线程 string text; using (WebResponse response = req.EndGetResponse(ar)) { StreamReader reader; using (reader = new StreamReader(response.GetResponseStream())) { text = reader.ReadToEnd(); } msdnData = ProcessFeed(text); } Trace.Warn("结束异步 当前线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); } protected override void OnSaveStateComplete(EventArgs e) { Trace.Warn("当前线程:" + Thread.CurrentThread.ManagedThreadId.ToString()); } string ProcessFeed(string feed) { //来自XML输入,创建页面输出 return Server.HtmlDecode(feed); } }
- 实现异步页面的两种用法
- 页面框架的两种实现
- AsyncTask异步任务-两种用法
- GCD实现异步任务同步的两种方式
- 两种JSP页面include用法的区别
- 两种定时刷新局部页面的方法--采用异步流程
- 页面滚动时,异步加载的实现
- 实现页面图片的延时异步加载
- android handler的两种用法(一种UI线程,另一种用于执行异步任务)
- 用javascript实现页面重载的两种做法
- PHP生成静态页面的两种实现方法
- 网页里实现页面折叠的两种方法
- servlet 实现页面跳转的两种方法
- PHP程序实现支持页面后退的两种方法
- php实现伪静态化页面的两种方法
- javascript实现页面跳转的两种方式
- 页面跳转的两种实现方式 详解
- jsp实现页面跳转的两种方法
- ARC 入门已经使用
- 数组元素乘法结果
- HDU 2830 Matrix Swapping II
- 数组与字符串、字符指针与其他类型指针、赋值参数、指针参数以及引用参数、函数指针
- HowTo: Debug Crashed Linux Application Core Files Like A Pro
- 实现异步页面的两种用法
- ios数据存储小结
- lucene结构详解之三域 (Field) 的数据信息(.fdt,.fdx)
- autobiography——John. S. Mill
- [人搜]人搜面试摘录
- 0.ring3-反调试-CheckRemoteDebuggerPresent(ProcessDebugPort)
- latex初步学习
- 表达式计算: 分析与设计
- automake 共享库