0

昨天朋友开发中遇到个有意思的问题找我去帮忙

他是用asp.net普通的web应用程序开发的

因为是公安的项目,涉及到很多大数据查询,这个不是重点,重点是当有查询操作时,再点击本网站的其他链接都会进入假死状态,待查询结束后服务端才会有所相应,查询时就算新建浏览器窗口都无法访问该站,也是只能等待查询结束才可以。

 

排错时经过删减代码,一直到最后,已经移除全部数据库操作,只采用线程sleep来模拟等待,问题依旧,所以看出来与数据库无关,依然所有的操作表现得都像是一个队列,最后的结论我自己都不敢相信,难道.net处理web客户端响应竟然是单线程的??

 

百度一番,果然如此- -|||asp.net中同一session的处理是单线程的,网上贴出的代码中可以看到处理中有类似state.lock的处理,在webconfig中禁用session:<sessionState mode="Off"></sessionState>果然问题不再。

没经测试,但是猜测页面级别的禁用也可以达到同样的效果,在页面顶端page定义时加入EnableSessionState="False"。

 

以下引用一段msdn的原文:

 

并发请求和会话状态
对 ASP.NET 会话状态的访问专属于每个会话,这意味着如果两个不同的用户同时发送请求,则会同时授予对每个单独会话的访问。但是,如果这两个并发请求是针对同一会话的(即,使用相同的 SessionID 值),则接收到的第一个请求获得对会话信息的独占访问权,而第二个请求将在第一个请求完成之后执行,或直到由于第一个请求超过锁定超时时间而释放对该信息的独占锁定后再执行。如果将 EnableSessionState 页指令设置为 ReadOnly,则对只读会话信息的请求不会导致对会话数据的独占锁定。可能仍需等到会话数据由读写请求而获得的锁定被解除后,对会话数据的只读请求才能得到满足。

 

这种设计实际本身是没有问题的,安全第一么,但是不能否认的是在99%的情况下,这种表现是脑残的- -

所以从此又多了一个无视session的理由,还是用cookie吧:-)

 

 

---------------------扩展------------------------------------------------------------

在这篇文章(《session,有没有必要使用它?》)中,介绍了一个更简便、靠谱的解决方案,并且也比我这篇有深度的多:-)

<sessionState mode="Custom" customProvider="CookieSessionStateStore">
    <providers>
        <add name="ProcCacheSessionStateStore" type="Fish.SampleCode.ProcCacheSessionStateStore"/>
        <add name="CookieSessionStateStore" type="Fish.SampleCode.CookieSessionStateStore"/>
    </providers>
</sessionState>

 

转自:http://hi.baidu.com/papercut/item/b7e7cca58216b7db5af19172

 

--------------------------------------------------------------------------------------------------------------------------------

     前年有个Asp.net项目上线后,正常情况下大部分页面打开速度都很快,但个别页面处理速度较慢。奇怪的是一旦访问个别速度慢的页面后,在该页面还未响应完毕前再去访问任何其他页面都需要等待很久才有响应。

     经过仔细分析和查找,原来发现罪魁祸首是Session阻塞造成的。默认情况下session状态是“可写状态”(EnableSessionState=”true”),即当用户打开任何一个页面时,该页面的Session就会持有一个写锁定,写锁定会阻塞所有的读写锁定,故只有等该页面处理完毕后才释放对应的Session写锁定,在释放之前访问其他页面时将被阻塞住。详细描述如下:

      当页面对Session具有可写功能(即页面有<%@ Page EnableSessionState="True" %>标记),此时直到请求完成该页面的Session持有一个写锁定。 
      当页面对Session具有只读功能(即页面有<%@ Page EnableSessionState="ReadOnly" %>标记),此时知道请求完成该页面的Session持有一个读锁定。 
      读锁定将阻塞一个写锁定;读锁定不会阻塞读锁定;写锁定将阻塞所有的读写锁定。

 

   所以将各页面标记为<%@ Page EnableSessionState="ReadOnly" %>可解决此问题。也可在web.config中统一修改各页面的默认session状态:

   <pages validateRequest="false" enableSessionState="ReadOnly">
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </controls>
    </pages>


  对于个别页面确实需要写session权限的(例如有session[“aa”]=”bb”之类的操作),可以单独设置该页面标记为

<%@ Page EnableSessionState="True" %>

 

转自:http://www.cnblogs.com/qguohog/archive/2012/09/27/2705799.html

 

参考资料:

http://www.anqn.com/aspx/2010-04-30/a09126048.shtml
http://www.cnblogs.com/flier/archive/2004/08/07/30902.html

关闭 返回顶部
联系我们
Copyright © 2011. 聚财吧. All rights reserved.