zoukankan      html  css  js  c++  java
  • 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啊?

  • 相关阅读:
    'Undefined symbols for architecture i386,clang: error: linker command failed with exit code 1
    The codesign tool requires there only be one 解决办法
    XCode iOS project only shows “My Mac 64bit” but not simulator or device
    Provisioning profile XXXX can't be found 的解决办法
    UIView 中的控件事件穿透 Passthrough 的实现
    Xcode4.5出现时的OC新语法
    xcode 快捷键(持续更新)
    打越狱包
    php缓存与加速分析与汇总
    浏览器的判断
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/1664123.html
Copyright © 2011-2022 走看看