Leveraging the Power of Asynchrony in ASP.NET [转]
Asynchronous programming has had a lot of attention in the last couple of years and there are two key reasons for this: First it helps in providing a better user experience by not blocking the UI thread which avoids the hanging of the UI screen until the processing is done, and second, it helps in scaling up the system drastically without adding any extra hardware.
But writing asynchronous code and managing the thread gracefully was a tedious task. But as the benefits are tremendous, many new technologies and old technologies have started embracing it. Microsoft has also invested a lot in it since .NET 4.0 and then in .NET 4.5, they made it simpler than ever with the introduction of async and the await keyword.
However, asynchrony has been usable in ASP.NET since the beginning but has never gotten the required attention. And given the way requests are handled by ASP.NET and IIS, asynchrony could be much more beneficial and we can easily scale up our ASP.NET applications drastically. With the introduction of new programming constructs like async and await, it’s high time that we start leveraging the power of asynchronous programming.
In this post, we are going to discuss the way requests are processed by IIS and ASP.NET, then we will see the places where we can introduce asynchrony in ASP.NET and discuss various scenarios where we can gain maximum benefits from it.
How are requests handled?
Every ASP.NET request has to go through IIS then is ultimately handled by ASP.NET handlers. A request is first received by IIS and after initial processing, forwards to ASP.NET which actually handles the request (for an ASP.NET request) and generates the response. This response is then sent back to the client via IIS. IIS has some worker threads that are responsible for taking the request from the queue and executing IIS modules and then forwarding the request to ASP.NET queue. ASP.NET doesn’t create any thread or own any thread pool to handle the request, instead it uses the CLR thread pool and gets the thread from there to handle the requests. The IIS module calls ThreadPool.QueueUserWorkItem which queues the request to CLR worker threads. As we know, the CLR thread pool is managed by CLR and self-tuned (meaning it creates/destroys the threads based on need). Also, we should keep in mind that creating and destroying a thread is always a heavy task and that’s why this pool allows us to reuse the same thread for multiple tasks. So let’s see pictorially the way a request gets processed.
In the above pic, we can see that a request is first received by HTTP.sys and added in the queue of the corresponding application pool at kernel level. One IIS worker thread takes the request from the queue and passes it to the ASP.NET queue after its processing. The request may get returned from IIS itself if it is not an ASP.NET Request. A thread from the CLR thread pool gets assigned to the thread that’s responsible for processing the request.
When should Asynchrony be used in ASP.NET?
Any request can broadly be divided in two types:
1- CPU Bound
2- I/O Bound
A CPU bound request needs CPU time and is executed in same process, while I/O bound requests are blocking in nature and dependent on other modules which do the I/O operations and return the response. Blocking requests are one of the major roadblocks for high scalable applications and in most of our web application we been wasting lots of time while waiting for I/O operations. These are the following scenarios where asynchrony should be used:
1- For I/O Bound requests including
- Database access
- Reading/Writing Files
- Web Service calls
- Accessing Network resources
2- Event driven requests like SignalR
3- Where we need to get the data from multiple sources
Let’s create an example where we would create a simple Synchronous Page and then will convert it to an asynchronous page. For this example, I have put a delay of 1000ms (to mimic some heavy calls like Database/web service calls, etc.) and also downloaded one page using the WebClient as follows:
protected void Page_Load(object sender, EventArgs e)
{
System.Threading.Thread.Sleep();
WebClient client = new WebClient();
string downloadedContent = client.DownloadString("https://msdn.microsoft.com/en-us/library/hh873175%28v=vs.110%29.aspx");
dvcontainer.InnerHtml = downloadedContent;
}
Now we will convert this page to an asynchronous page. There are mainly three steps involved here
- Change it to asynchronous page by adding Async = true in the page directive as follows:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Home.aspx.cs" Inherits="AsyncTest.Home" Async="true" AsyncTimeout="3000" %>
I have also added AsyncTimeout (which is optional) but we can define based on our requirement.
- Convert the method to an Asynchronous one. Here we convert Thread.Sleep and client.DownloadString to the asynchronous method as follows:
private async Task AsyncWork()
{
await Task.Delay(); WebClient client = new WebClient(); string downloadedContent = await client.DownloadStringTaskAsync("https://msdn.microsoft.com/en-us/library/hh873175%28v=vs.110%29.aspx "); dvcontainer.InnerHtml = downloadedContent; }
- Now we can call this method directly at Page_Load and make it asynchronous as follows:
protected async void Page_Load(object sender, EventArgs e)
{
await AsyncWork();
}
But here Page_Load returns the type is async void which should be avoided in almost all cases. As we know the flow of the page life cycle, Page_Load is a part of life cycle and if we set it as async then there could be scenarios and other events where the lifecycle may get executed even if the page load is still running. It is highly recommended we use RegisterAsyncTask which allows us to register the asynchronous method which is executed during the lifecycle while it is most appropriate and avoids any issue. So we should write it as follows:
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(AsyncWork));
}
Now we have converted our page as asynchronous and it won’t be a blocking request.
I deployed both applications on IIS 8.5 and tested them with burst load. For the same machine configuration, the synchronous page was able to take just 1,000 requests in 2-3 seconds while the asynchronous page was able to serve more than 2,200 requests. After that, we started getting Timeout or Server Not Available errors. Although the average request processing time isn’t much different, we were able to serve more than 2X the requests just by making the page asynchronous. If that isn’t proof we should leverage the power of asynchronous programming, I don’t know what is!
There are some other places where we can introduce asynchrony in ASP.NET too:
1- By writing asynchronous modules
2- By writing Asynchronous HTTP Handlers using IHttpAsyncHandler or HttpTaskAsyncHandler
3- Using web sockets or SignalR
Conclusion
In this post, we discussed asynchronous programming and saw that with the help of new async and await keywords, writing asynchronous code is very easy. We covered the topic of request processing by IIS and ASP.NET and discussed the scenarios where asynchrony can be more fruitful, and we also created a simple example and discussed the benefits of asynchronous pages. Last we explored some places where asynchrony can be leveraged in ASP.NET.
Thanks for reading!
http://news.oneapm.com/advantage/
Leveraging the Power of Asynchrony in ASP.NET [转]的更多相关文章
- (翻译)《Hands-on Node.js》—— Introduction
今天开始会和大熊君{{bb}}一起着手翻译node的系列外文书籍,大熊负责翻译<Node.js IN ACTION>一书,而我暂时负责翻译这本<Hands-on Node.js> ...
- Announcing Microsoft Research Open Data – Datasets by Microsoft Research now available in the cloud
The Microsoft Research Outreach team has worked extensively with the external research community to ...
- WM-N-BM-09 WM-N-BM-14
USI Delivers WICED Module to Gain Great Success Customers Broadcom’s Wireless Internet Connectivity ...
- Hadoop vs Elasticsearch – Which one is More Useful
Hadoop vs Elasticsearch – Which one is More Useful Difference Between Hadoop and Elasticsearch H ...
- 通过利用immutability的能力编写更安全和更整洁的代码
通过利用immutability的能力编写更安全和更整洁的代码 原文:Write safer and cleaner code by leveraging the power of "Imm ...
- 【内推】微软北京深圳招聘多名Cloud Solution Architect
Azure is the most comprehensive, innovative and flexible cloud platform today and Microsoft is hirin ...
- [ABP] ASP.NET Zero 5.6.0 之 ASP.NET Zero Power Tools 上手日志
之前破解了这个工具后,却没有使用它. 现在使用这个小工具,帮我完成创建Entity类,Dto类,AppService类,View视图等DDD相关工作以及Entity Framework Migrati ...
- [ABP] ASP.NET Zero 5.6.0 之 ASP.NET Zero Power Tools 破解日志
两个要破解Patch的关键dll名称:AspNetZeroRadToolVisualStudioExtension.dll和AspNetZeroRadTool.dll AspNetZeroRadToo ...
- 【C#】转一篇MSDN杂志文:ASP.NET Pipeline: Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code
序:这是一篇发表在2003年6月刊的MSDN Magazine的文章,现在已经不能在线阅读,只提供chm下载.讲的是异步请求处理那些事,正是我上一篇博文涉及的东西(BTW,事实上这篇杂志阐述了那么搞然 ...
随机推荐
- Cocos2d-x 3.0 cocostudio骨骼动画的动态换肤
概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现.在接下来的这个Demo ...
- IOS 学习笔记 20150314
Objective--C 类与对象 1 关键字 @interace 类定义 @end 类结束 @implementation 类实现 : 继承 @public 公用 @private 私有 @prot ...
- 解决 nginx 返回数据不完整的方法
通过PHP请求接口时发现接口的内容输出没有完整的返回整个数据,早上只修改了nginx api_metrics插件里的计算response大小的代码,观察日志发现一条: 2012/08/28 02:13 ...
- Eclipse+Tomcat WEB开发配置
关键字:JDK,WEB,Eclipse,Tomcat OS: Windows 8.1 with update 1.下载安装JDK:http://www.oracle.com/technetwork/j ...
- Asp.net MVC2中你必须知道的扩展点(一):Controller Factory
Asp.net mvc2中提供很多可以扩展的地方,利用这些扩展之后,asp.net mvc使用起来更加灵活.Simone Chiaretta曾写过一篇文章:13 ASP.NET MVC extensi ...
- IEnumerable,ICollection,IList,List区别
做C#的同学们,都知道,一类只能有一个继承类,但可以实现多个接口.这句话就告诉我们:IEnumerable,ICollection,IList,List区别了 首先我看看 IEnumerable: / ...
- Apple 公司开发者账号注册
苹果公司开发者账号注册流程详解 这段时间在给朋友申请苹果账号,从个人开发者账号.公司账号到企业账号,申请了个遍.这里对申请流程做一下介绍,方便其他朋友,少走弯路,账号早日申请通过. 1.首先介绍下 ...
- 【技术贴】Maven打包文件增加时间后缀
构建war包,或者jar包的,时候,maven会自动增加一个版本号和时间放在jar包后面比如poi-3.9-20131115.jar这样子,但是我自己打war包,总是给我生成一个快照的后缀report ...
- Central Europe Regional Contest 2012 Problem I: The Dragon and the Knights
一个简单的题: 感觉像计算几何,其实并用不到什么计算几何的知识: 方法: 首先对每条边判断一下,看他们能够把平面分成多少份: 然后用边来对点划分集合,首先初始化为一个集合: 最后如果点的集合等于平面的 ...
- maven安装和环境变量配置
maven安装和环境变量配置 myeclipse自带maven(Maven4MyEclipse)创建项目:新建Web Projects项目,在新建的页面上打上maven的勾.新建的项目里会多出个pom ...