实现异步页面的两种用法

来源:互联网 发布:融资租赁业务软件 编辑:程序博客网 时间: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);         }     }


 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 排卵期下腹隐隐作痛 排卵期会有很多白带吗 排卵期身体有什么反应 过了排卵期会怀孕吗 排卵期有什么症状腰痛 排卵期计算法周期表 女人的排卵期怎么算 排卵期排出褐色分泌物 女生排卵期有什么反应 排卵期出血的症状和图片 排卵期症状有哪些症状 排卵期是不是容易怀孕 一个月排卵期有几天 排卵期肚子痛怎么回事 排卵期体温会升高吗 排卵期测体温怎么测 排卵期肚子疼是在排卵吗 排卵期腰痛是怎么回事 排卵期没有射会怀孕吗 女人排卵期计算方法 排卵期有什么症状白带 排卵期是什么时候有什么反应 女孩排卵期是什么时候 排卵期不带套子外射会怀孕吗 排卵期怎么算计算器 女的排卵期是什么时候 女生排卵期有什么特征 排卵期一定会怀孕吗 排卵期小肚子疼是怎么回事 排卵期身体有什么症状 女人的排卵期怎么算才准确 女性排卵期有什么症状 什么是排卵期怎么计算 排卵期第几天容易怀孕 排卵期是什么时候到什么时候 排卵期有什么症状或感觉 排卵期体重会增加吗 排卵期受完孕有什么感觉 排卵期出血可以运动吗 排卵期为什么没怀上 排卵期出血一般几天