如果在两个瀏覽器中,打开同一个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
结果很明显,asp.net对于同一个Session,居然是单线程执行,到底发生了什么?
可能眼尖的TX,发现了在b.aspx中,有一行代码似乎很扎眼
Session["TestKey"] = "test";为什么要加这一行?不加会怎么样?
你猜得没错,不加就是并行执行,任你第一个的执行时间再怎么长,我第二个都会侧着身子,全身而退。
注释这行代码测试一下,不过记得关掉刚才那个窗口,重新打开一个(因为刚才那个窗口已写入了Session的Cookie值,所以asp.net还是认为是有Session存在的)
到这里,结论好像很简单了,对于同一个Session,asp.net单线程执行。
找找原因
翻出.net 源代码,在System.Web.State.InProcStateClientManager的DoGet方法中找到了关键代码
图中可以看出state对象,一定会被某次session的第一个request给锁住,
同一个session的其它request,你就慢慢等着第一个执行完再解锁吧
继续~
被锁后SessionStateModule的GetSessionStateItem方法返回locked为true
isCompleted自然就设定为false了,而BeginAcquireState方法的_rqAr.CompletedSynchronously也就没机会调用Complete方法改为true
因此HttpApplication,也就没办法执行这次请求的后半段(_endHandler),也就是aspx页的代码了,这也是我们测试时第二个请求在等第一个请求完成的原因
最后结论,asp.net中如果用了Session,就别想并行执行了,虽然很多时候,并不会有什么问题,但是对于ajax程式来说,客户端费尽心思的的多个异步请求,也变成了笑话,因为服务器端实际上还是one by one在执行,就算你发再多请求过去又有什么用,用户还是:
我等得花儿也谢了~
PS:找到原因后也很庆幸,现在开发的框架和制定的规范,里面除了个别地方为了提高性能以外,其它任何地方都禁止使用session,永远为客户端提供无状态,可重入的http服务,保证可靠的web调用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库