我只被发现在 ASP.Net web 应用程序中的每个请求获取会话锁的请求,开头和结尾的请求释放 !

在的情况下意义上,起初找我的丢失,这基本上意味着︰

  • 只要花费很长时间才能加载 (可能是因为速度慢的数据库调用或其他),ASP.Net 网页和用户决定他们想要导航到另一页,因为他们厌倦了等待,他们不能 !ASP.Net 会话锁定强制新页请求,等待,直到在原始请求完成它带来痛苦的煎熬的负载。Arrrgh。

  • 任何时候 UpdatePanel 正在加载速度很慢,和用户决定在 UpdatePanel 已完成更新之前导航到另一页...他们不能 !ASP.net 会话锁定强制新页请求,等待,直到在原始请求完成它带来痛苦的煎熬的负载。双 Arrrgh !

因此选项是什么?到目前为止我已经想出了用︰

  • 实现自定义 SessionStateDataStore,ASP.Net 支持的。我找不到太多无法复制,在那里,似乎之类的高风险,容易把事情搞糟。
  • 跟踪的进度中的所有请求,请求来自同一个用户,如果取消原来的请求。似乎很极端,但这种将工作 (我认为)。
  • 不要使用会话 !当用户需要使用某种类型的状态时,我无法只是相反,使用缓存,关键项目的经过身份验证的用户名或某些此类的事情上。再次看起来有点极端。

我真的不能相信 ASP.Net Microsoft 小组会保留这种极大的性能瓶颈框架在 4.0 版中 !我缺少明显的特征?力度是否会为会话使用 ThreadSafe 集合?

2010-09-02 17:44:38
问题评论:

好了,我正在有点开玩笑我标题。尽管如此,IMHO chocking 框中实现的出施加的性能是会话的出人意料。此外,我敢打赌堆栈溢出专家不得不做大量高度自定义的开发,以获得性能和可扩展性,实现了他们的和对他们的感谢。最后,堆栈溢出是 MVC 应用程序、 不 WebForms,我敢打赌,这有助于 (尽管不可否认它们仍使用相同的会话基础结构)。

-1︰ 从假的前提开始

文章对此从 MVC 角度︰ stefanprodan.eu/2012/02/...

如果 Joel Mueller 提供给您的信息以解决您的问题,为什么没有标记正确回答他的答案吗?只是思想。

@ars265-Joel Muller 提供良好的信息,很多,我想要感谢他的。但是,我最终就与比在他的博客文章建议一个不同的路线。因此,将不同文章标记为答案。

回答:

如果您的网页不会修改任何会话变量,您可以取消大部分此锁。

<% @Page EnableSessionState="ReadOnly" %>

如果您的网页不能读取任何会话变量,您可以取消此锁完全,该页面。

<% @Page EnableSessionState="False" %>

如果没有您的网页使用会话变量,只需关闭在 web.config 中的会话状态。

<sessionState mode="Off" />

我很好奇,什么您认为"ThreadSafe 集合"一样成为线程安全的如果它不使用锁?

编辑︰ 我应该大概能够说明由"退出该锁的大多数"的含义。而不会阻塞其他,可以为给定会话在同一时间处理任意数量的读取仅会话或无会话页。但是,读写会话页面不能开始处理直到所有只读的请求已完成,并且正在运行时它必须具有独占访问该用户的会话,以保持一致性。各个值锁定行不通,因为如果一个页面更改相关值作为一组一组吗?您应确保同时运行其他网页会有一致的视图的用户的会话变量?

我建议您试着最小化修改会话变量,它们有设置后,如果可能的话。这样,您可以使您的网页的大部分读仅会话页,增加来自同一个用户的多个同时请求不会阻止对方的机会。

Hi Joel 感谢在此回答时间。这些都是一些好的建议和一些精神食粮。我不懂您说会话的所有值必须以独占方式都锁定跨整个请求的原因。由任何线程,可以在任何时候更改 ASP.Net 缓存值。为什么这是不同会话?有点离题了-我具有只读选项的一个问题是如果开发人员不会将值添加到会话时只读模式,则它会自动失败 (没有例外)。事实上,它会保留请求-但不是超出其余的值。

@James-我只猜在这里,设计人员的动机,但我假设它是更常见的是具有多个相互依赖与单个用户的会话中随时可以缺少使用或内存过低的原因,导致清除高速缓存中的值。如果一个页面设置 4 相关的会话变量,而另一个阅读两个修改后,很容易会导致到某些非常困难-到-诊断错误。我设想设计人员选择查看"用户会话的当前状态"作为一个单元锁定为此目的。

因此开发一个系统,解决了不能找出锁定小公分程序员?目的是要启用 IIS 实例之间存储共享会话的服务器场的网站?您能否举例说明将存储在会话变量中的内容吗?我无法想出任何东西。

是的这是目的之一。负载平衡和冗余基础结构中实现时,重新考虑各种方案。当用户在网页上的工作,即他输入在窗体中的数据,让我们说,5 分钟,webfarm 崩溃-中的某些内容的一个节点的 powersource 转吹-用户应该不会注意到的。他不能将开始时间到会话之外只是因为他的会话已断开,仅仅因为他工作进程不再存在。这意味着,若要处理完美平衡/冗余,会话必须外部化从辅助节点.

退出的另一种有用程度是<pages enableSessionState="ReadOnly" />在 web.config 和使用 @Page 来启用书写在特定的页面上。

好了,对他的所有输入的 Joel Muller 大属性。我最终的解决方案就是使用自定义 SessionStateModule,详细信息请参阅 MSDN 文章的结尾︰

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx

这就是︰

  • 非常快,来实现 (实际上 seemed 变得更容易比通过提供路由)
  • 使用了大量现成的 (通过 SessionStateUtility 类中) 处理在标准 ASP.Net 会话

这已为"snapiness"感觉差别巨大我们的应用程序。我仍然无法相信 ASP.Net 会话锁定整个请求的会话的自定义实现。这为网站增加了这种巨大的 sluggishness。判断在线我所要做的研究 (和几个真正有经验的 ASP.Net 开发人员交谈) 的量,很多人都遇到了此问题,但很少有人有曾经到底部的原因了。也许我会写信给 Scott Gu...

我希望这有助于有一小部分人 !

引用是有趣的查找,但我必须提醒各位有关的几种方法的示例代码都有一些问题︰ 第一, ReaderWriterLock已不再支持ReaderWriterLockSlim -应改为使用的。第二,lock (typeof(...))也已经不建议使用-您应锁定改为私有静态对象实例上。第三,短语"此应用程序不会防止并发的 Web 请求使用相同的会话标识符"是一个警告,而不是功能。

如果您想要避免难重现错误负载的情况下,我认为可以进行此项工作,但必须将使用SessionStateItemCollection中的示例代码替换 (可能是基于ConcurrentDictionary) 的线程安全类。

我刚才到此稍多一些,和遗憾的是, ISessionStateItemCollection需要为System.Collections.Specialized.NameObjectCollectionBase.KeysCollection -没有公共构造函数的类型的Keys属性。哎呀,谢谢专家。这是非常方便的。

好吧,我相信我最后有一个完整的 threadsafe 的非读取锁定的会话工作实现。最后一个步骤涉及到实现自定义的 threadsafe SessionStateItem 集合,而基于 MDSN 文章链接到上面的注释中。与此谜题的最后一个部分创建基于本文很好的 threadsafe 枚举数︰ codeproject.com/KB/cs/safe_enumerable.aspx.

杰姆斯-显然这是一个很旧的话题,但是我想知道您是否可以共享您的终极解决方案呢?我试着跟着使用以上的评论的线程,但到目前为止尚未能获得工作的解决方案。我可以相当肯定没有任何基本在我们有限的使用者需要锁定的会话中。

我开始使用AngiesList.Redis.RedisSessionStateModule,哪个搁置那样 (我使用windows 端口— 尽管还没有MSOpenTech 端口) 的存储中使用Redis 服务器(很快),绝对没有锁定的会话。

在我看来,如果您的应用程序的结构以合理的方式,这不是问题。如果会话的一部分作为实际需要锁定的、 一致的数据,则应专门实现锁/并发检查。

决定,将每个 ASP.NET 会话被锁定默认情况下只是为了处理应用程序设计拙劣的 MS 是错误的决策,在我看来。尤其是因为大多数开发人员没有不意识到好像被锁定的会话,更不用说应用程序显然需要被组织成要做到尽可能的只读会话状态 (选择退出,如有可能)。

除非您的应用程序有特殊需要我认为有 2 的方法︰

  1. 根本不使用会话
  2. 使用会话视为是,执行微调 joel 提到。

会话是线程安全不仅还状态安全,方式完成当前的请求后,才知道,每个会话变量不会更改另一个活动的请求。为了使这种情况您必须确保当前请求之前将锁定该会话已完成。

您可以创建行为类似会话通过多种方式,但如果它不会锁定当前会话,则不会是会话。

有关的具体问题,你提到我认为您应该检查HttpContext.Current.Response.IsClientConnected这会很有用到以防止不必要执行和等待客户端,虽然因为这可只有被共用,它不能完全解决这一问题的方法并不是异步。

我准备根据张贴在该线程中的链接的库。它使用从 MSDN 和 CodeProject 的示例。这要归功于杰姆斯。

我也使 Joel Mueller 建议的修改。

代码在这里︰

https://github.com/dermeister0/LockFreeSessionState

哈希表模块︰

Install-Package Heavysoft.LockFreeSessionState.HashTable

ScaleOut StateServer 模块︰

Install-Package Heavysoft.LockFreeSessionState.Soss

自定义模块︰

Install-Package Heavysoft.LockFreeSessionState.Common

如果要实现支持 Memcached 或 Redis,安装此包。然后, LockFreeSessionStateModule类继承并实现抽象方法。

但生产上不测试代码。此外需要改进的错误处理。在当前实现中没有捕捉的异常。

Redis 使用一些无锁定的会话提供程序︰

它需要通过不是免费的 ScaleOut 解决方案库?

是的我创建了仅用于 SOSS。您可以使用提到的 Redis 会话提供程序,它是免费的。

请输入您的翻译

I just discovered why all ASP.Net websites are slow, and I am trying to work out what to do about it

确认取消