asp.net真的是并行处理request的吗?

asp.net真的是并行处理request的吗?

如果在两个瀏覽器中,打开同一个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调用

 

 

我和你的结论有微妙不同
1 只要写session 就必须锁
2 读session其实不需要锁
3 无论是什么机制 只要是并发集合写 就一定要锁

所以
a“找一个替代Session的解决方案”
找一个安全的替代目前Session实现的无锁解决方案 其实是不存在的 因为并发读写集合,本质上的锁是存在的 只是实现的优劣不同。 就算用并发字典也不过是内部用了更加小粒度的锁 并非无锁雾消耗,可能还没有下面b说的方式来得优化。


b“不放弃Session,上面的问题就没办法解决”。

不放弃session 只在需要写session的个别页面时候上锁 其他页面都标记readonly 能够避免绝大多数锁消耗,也就是说不写session的页面只要标记为readonly就能并发了 那还纠结个啥,一共才几个页面需要写session啊?

 

放弃Session的配置

访问ASP.NET session state独占每一个session,就是如果两不同的用户产生并发请求,访问每一个单独的session被认为是并发.可是,如果两个并发请求产生同一个session,(使用同一个sessionID值),在首先请求的首先得到唯一访问session信息.第二个请求执行的只能在第一个去请求访问结束后得到(第二个session才能得到访问.因为如果第一次请求已经超时,锁住信息就被释放.)如果在@Page中的EnableSessionState设置为ReadOnly,一个请求read-only session的信息,在锁住Session数据时没有返回结果,可是,read-only请求session数据也许仍然在等待一个已琐的read-write请求的session 数据被清出.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值