美文网首页
ASP.NET SessionState 解惑

ASP.NET SessionState 解惑

作者: lazio | 来源:发表于2016-07-11 08:47 被阅读46次

    踩坑

    近日在对一个ASP.NET WEBFORM项目进行调优过程中,偶然发现页面POSTBACK事件是串行处理的,甚至不同页面的请求都是串行处理的(一个页面加载完毕后,才开始加载第二个页面)。但是网站明明是并发处理请求的啊,当时十分不解,把代码翻来覆去排查了大半天,寻找业务框架中什么地方是不是锁了资源。各种断点、调试、日志全部用上,还是找不到原因。
    仔细思考了一下,ASP.NET肯定不会是串行处理的,难道是某一个Session中,ASP.NET对其串行处理请求?

    排雷

    在项目中新增一个页面,只能加最简单的事件代码:

      log.Info("start");
      System.Threading.Thread.Sleep(5000);
      log.Info("end");
    

    浏览器中开打两个标签页同时访问该页面,结果请求时并行处理的。

    16:24:44[9]start
    16:24:45[10]start
    16:24:49[9]end
    16:24:50[10]end
    

    接着先访问下登陆页面,然后再重复上次动作,请求变成串行处理了!

    16:26:11[9]start
    16:26:16[9]end
    16:26:16[10]start
    16:26:21[10]end
    

    换成两个浏览器,分别登陆后访问该页面,请求被并行处理。
    自此确认肯定是SESSION的问题!

    GOOGLE搜索了一番,找到原因及解决方案:

    The session state module implements a locking mechanism and queues the access to state values. A page that has session-state write access will hold a writer lock on the session until the request finishes. A page gains write access to the session state by setting the EnableSessionState attribute on the @Page directive to True. A page that has session-state read access -- for example, when the EnableSessionState attribute is set to ReadOnly -- will hold a reader lock on the session until the request finishes.

    SessionStateModule源码

    原来SessionStateModule模块实现了一个写入锁,并对其进行排队处理,所以同一SESSION下的所有请求都会被串行执行。

    解决方案也很简单,在页面上增加EnableSessionState="ReadOnly"指令即可。 当然,增加了这个指令后,这个页面也就不能修改SESSION值了。

    衍生

    GOOGLE的过程中,发现.NET MVC同样也有这个问题,其解决方案是在controller上增加特性[SessionState(SessionStateBehavior.ReadOnly)]

    随手实验一番,不加以上特性时,在有SESSION的情况下,同SESSION的请求会被串行处理。增加SessionStateBehavior.ReadOnly后不同action中,请求会被并行处理,但是相同action仍然是串行处理的。
    即使是Task<ActionResult>,任然无法逃脱串行执行的魔掌。

    相关文章

      网友评论

          本文标题:ASP.NET SessionState 解惑

          本文链接:https://www.haomeiwen.com/subject/lxzhjttx.html