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

推荐订阅源

WordPress大学
WordPress大学
A
About on SuperTechFans
量子位
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
Blog — PlanetScale
Blog — PlanetScale
Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX
Google DeepMind News
Google DeepMind News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
G
Google Developers Blog
U
Unit 42
D
DataBreaches.Net
博客园 - Franky
D
Docker
宝玉的分享
宝玉的分享
Y
Y Combinator Blog
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Hugging Face - Blog
Hugging Face - Blog

博客园 - Kevin Zou

vs2008 ctrl+D 查找出错 No files were found to look in. Error while trying to retrieve text for error ORA-03113 的一种解决方式 IE不能直接顯示PDF的原因分析和解決方法 [2012-01-06] 流程系统设计--消息和通知 企业应用整合(1)--一个账号 2010年终随笔--漫谈技术 Schtasks命令理解排程的應用 用Adobe ImageReady制作简单GIF动画 Console输出UTF-8 JQuery1.4+ Ajax IE8 内存泄漏 权限设计的三层境界续 闲话权限设计三层境界 - Kevin Zou - 博客园 一个时代的终结 Jquery乱码的一次解决过程 十年磨一剑—序 十年磨一剑--缓存模块设计 系统设计其实很有趣--从业务逻辑谈起 系统架构随笔--我看三层架构的数据访问层"怪胎"
asp.net真的是并行处理request的吗?
Kevin Zou · 2010-02-04 · via 博客园 - Kevin Zou

如果在两个瀏覽器中,打开同一个web系统的两支asp.net程式,这2支程式会并行执行吗?

那么在一个瀏覽器中打开这两支程式呢?

第一种情况,可能很容易就知道是并行的,因为不管IE还是chrome,或是其它瀏覽器,在一个窗口中,一般都是共用一个session,因此这种情况,和两台不同的机器的请求应该是一样的。

然而对于第二种,情况就不那么简单了。

先做个简单的试验

1.新建web站台,增加a.aspx和b.aspx

a.aspx:

<%@ Page Language="C#" %>
<%
System.Threading.Thread.Sleep(10000);   //睡10秒,在这个长时间的执行过程中,还容得下其它请求吗?
%>
Hello,A.aspx

b.aspx:

<%@ Page Language="C#" %>
<%
Session["TestKey"] = "test";
%>
Hello,B.aspx

2.开启IE8,用两个Tab,分别瀏覽a.aspx和b.aspx

test2

test3

test5test4

结果很明显,asp.net对于同一个Session,居然是单线程执行,到底发生了什么?

可能眼尖的TX,发现了在b.aspx中,有一行代码似乎很扎眼

Session["TestKey"] = "test";

为什么要加这一行?不加会怎么样?

你猜得没错,不加就是并行执行,任你第一个的执行时间再怎么长,我第二个都会侧着身子,全身而退。

注释这行代码测试一下,不过记得关掉刚才那个窗口,重新打开一个(因为刚才那个窗口已写入了Session的Cookie值,所以asp.net还是认为是有Session存在的)

到这里,结论好像很简单了,对于同一个Session,asp.net单线程执行

找找原因

翻出.net 源代码,在System.Web.State.InProcStateClientManagerDoGet方法中找到了关键代码

test6

图中可以看出state对象,一定会被某次session的第一个request给锁住,

同一个session的其它request,你就慢慢等着第一个执行完再解锁吧

继续~

被锁后SessionStateModule的GetSessionStateItem方法返回locked为true

test7

isCompleted自然就设定为false了,而BeginAcquireState方法的_rqAr.CompletedSynchronously也就没机会调用Complete方法改为true

test8

因此HttpApplication,也就没办法执行这次请求的后半段(_endHandler),也就是aspx页的代码了,这也是我们测试时第二个请求在等第一个请求完成的原因

test9

最后结论,asp.net中如果用了Session,就别想并行执行了,虽然很多时候,并不会有什么问题,但是对于ajax程式来说,客户端费尽心思的的多个异步请求,也变成了笑话,因为服务器端实际上还是one by one在执行,就算你发再多请求过去又有什么用,用户还是:

我等得花儿也谢了~

PS:找到原因后也很庆幸,现在开发的框架和制定的规范,里面除了个别地方为了提高性能以外,其它任何地方都禁止使用session,永远为客户端提供无状态,可重入的http服务,保证可靠的web调用