惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Security Latest
Security Latest
博客园_首页
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Jina AI
Jina AI
爱范儿
爱范儿
小众软件
小众软件
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
博客园 - Franky
S
SegmentFault 最新的问题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
NISL@THU
NISL@THU
博客园 - 司徒正美
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
AWS News Blog
AWS News Blog
有赞技术团队
有赞技术团队
V
Visual Studio Blog
雷峰网
雷峰网
C
Cybersecurity and Infrastructure Security Agency CISA
美团技术团队
The Cloudflare Blog
P
Privacy & Cybersecurity Law Blog
Latest news
Latest news
S
Securelist
C
CERT Recently Published Vulnerability Notes
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Palo Alto Networks Blog
Last Week in AI
Last Week in AI
V
V2EX
Know Your Adversary
Know Your Adversary
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threat Research - Cisco Blogs
T
Tailwind CSS Blog
J
Java Code Geeks
I
Intezer
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园 - 【当耐特】
Schneier on Security
Schneier on Security

博客园 - Jun1st

Application之间共享Master Page ASP.NET AJAX 4的Client-Side Template和DataView ASP.NET AJAX 4的Client-Side Template和DataView 体验ASP.NET4之ClientID 体验ASP.NET 4之URL Routing 使用Extension Methods来使IDataReader更加方便 Custom WCF Configuration File USE HttpRuntime.Cache OVER HttpContext.Current.Cache IIS and VS Embedded Local Web Server Integrate jQuery with ASP.NET Data Controls Tech-Ed 2008 上海 ASP.NET MVC的分页和导航 LINQ and Pipeline Pattern Why Would a .Net Programmer Learn Ruby On Rails(翻译) ASP.NET MVC之AJAX Asp.Net MVC---Walkthrough Asp.Net MVC 入门篇——Overview Asp.Net 2.0之SqlCacheDependency Security Basics and ASP.NET Support(翻译)
Make Asynchronous Calls from Page
Jun1st · 2009-04-06 · via 博客园 - Jun1st

2009-04-06 14:22  Jun1st  阅读(1515)  评论()    收藏  举报

对于ASP.NET pages的请求需要有HTTP handler来处理,比如Page的instance。当有一个request来请求某个.aspx页面时,ASP.NET runtime会从ASP.NET thread pool中选一个thread来处理这个request, 并且在这个请求处理完成时释放这个thread。因此,如果这个  request请求的页面中的某一个Step花费了相对较长的时间,比如调用某个web service来获取数据,那么结果就是处理这个请求的thread会一直处于idle的状态,而不能处理新的请求。而之所以这个thread会处于idle的状态,是由于ASP.NET handler处理请求时采用的是同步的方式。

为了解决这个问题,在ASP.NET 1.0中可以通过实现IHTTPAsyncHandler来实现异步的方式。而在ASP.NET 2.0之后,实现异步方式变得了更加的简单了。本文就介绍两种实现异步的方法。

1. Asynchronous Pages

要将一个普通的ASP.NET页面变成一个asynchronous page,只需要在 @Page directive 设置 Async=”true 就可以了。

除此之外,还需要在Page_Load事件中来注册需要完成的异步事件。在Asynchronous page中,可以通过调AddOnPreRenderCompleteAsync这个方法来注册,注册一对Begin/End的event handler。

1:  AddOnPreRenderCompleteAsync(
2:                  new BeginEventHandler(BeginTask),
3:                  new EndEventHandler(EndTask));

BeginEventHandler的方法签名

IAsyncResult BeginTask(object sender, EventArgs e, AsyncCallback cb, object state)

EndEventHandler的方法签名就相对的简单了

void EndTask(IAsyncResult ar)

那么注册的异步事件是在什么时候被执行的呢?在PreRenderComplete之前你注册了异步事件,注册的BeginEventHandler事件就会开始执行。当异步事件执行完成后,Page就会从PreRenderComplete开始,继续完成生命周期中剩下的各个事件。为了验证异步事件是否确实是在这个PreRenderComplete事件中被执行的,我们可以再 Begin/End 事件中往页面的Trace中写入信息,并打开页面的Trace,然后看输出的Track信息

如下:

aspx.page

Begin PreRender

0.000143719091709968

0.000011

aspx.page

End PreRender

0.000170049306985077

0.000026

 

Begin asyc: Thread=6

0.00101590747269794

0.000846

 

End async: Thread=7

2.20676898637082

2.205753

aspx.page

Begin PreRenderComplete

2.20682859505263

0.000060

aspx.page

End PreRenderComplete

2.20684834271408

0.000020

从Trace信息中可以看出,注册的异步事件就是在PreRenderPreRenderComplete之间执行的。

2. RegisterAsyncTask 方法

除了AddOnPreRenderCompleteAsync之外,还可以用 RegisterAsyncTask 来注册异步事件。甚至,RegisterAsyncTask 也许是一个更好的方法。

PageAsyncTask task = new PageAsyncTask(
    new BeginEventHandler(BeginTask),
    new EndEventHandler(EndTask),
    null,
    null);
 
RegisterAsyncTask(task);

RegisterAsyncTask 接受一个PageAsyncTask参数,这个task参数中可以设置的除了 Begin/End 事件外还可以做一些别的设置,如timeout时的handler等。timeout的默认时间是45秒,这个时间可以在 @Page directive中和web.config文件中进行设置

3. 两者比较
  1. RegisterAsyncTask 只是一个API方法,在异步和同步的页面中都可以使用。而AddOnPreRenderCompleteAsync只能在异步页面中使用
  2. RegisterAsyncTask end handler执行时,能够获得更多的信息,如HTTP context 信息。
  3. 当执行单个任务时,两者几乎一样,而当需要执行多个task时,则应该选用RegisterAsyncTask ,因为它允许多个任务同时执行
4. Aysnc-Compliant Action

什么样的操作应该或者建议使用async的操作呢? 大致上, CPU bound 或者 I/O bound的操作可以考虑采用异步的方式。尤其是在有大量IO操作的方法。这时,大量的时间都花费在了读取/写入或者操作数据上,这时,cpu就处于idle的状态,等待IO操作的完成

Sample

个人浅见,如果不足之处请指正,谢谢