【问题标题】:How does ASP.NET InProc session work? Are race conditions possible with read-only session?ASP.NET InProc 会话如何工作?只读会话是否可能出现竞争条件?
【发布时间】:2014-10-10 11:01:01
【问题描述】:

我想澄清一些 ASP.NET 会话的细节。我正在使用 ASP.NET MVC 3。
假设我有一个标有 [SessionState(SessionStateBehavior.ReadOnly)] 属性的控制器 - 所以它使用只读会话。
会话处于InProc 模式。
根据MSDN,对这个控制器的请求获得了一个读锁并且不能更新会话。
如果他们尝试更新会话值,我想了解这些请求(在一个公共会话内)之间是否仍然可能存在竞争条件
这些请求使用相同的会话数据结构,而不是单独的副本,对吧?
InProc 会话值如何更新?在请求结束时立即或在OnReleaseState 事件中?
OnReleaseState 处理程序会发生什么?

更新

我正在调查以下异常:

System.ArgumentException: Item has already been added. Key in dictionary: 'MyKey'  Key being added: 'MyKey'
at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
at System.Collections.Specialized.NameObjectCollectionBase.BaseAdd(String name, Object value)
at System.Web.SessionState.SessionStateItemCollection.set_Item(String name, Object value)

仅在访问会话的值时会发生这种情况:(DateTime)context.Session["MyKey"]

This post 描述了与 ASP.NET 会话非常相似的异常。

【问题讨论】:

    标签: asp.net .net asp.net-mvc session


    【解决方案1】:

    只要您只在 Session 中存储不可变对象,就没有竞争条件的风险。可以同时持有多个读锁,但持有写锁时不能获取读锁,持有读锁时不能获取写锁。

    如果您在 Session 中存储可变的、非线程安全的对象,然后将 Action 标记为使用只读 Session,您可能会遇到麻烦。

    在这种情况下,您将被阻止 (*) 在 Session 中添加/替换对象。

    (*) 实际上您可以添加/替换它们,但它们不会在请求结束后持续存在。

    但不会阻止您尝试改变 Session 中对象的状态。

    如果您的应用在 Session 中有可变对象,我建议您避免使用只读 Session。

    UPDATE响应cmets

    如果我尝试在阅读器锁定下设置值会怎样

    它只会在请求期间持续:您将处理 InProc Session 集合的浅表副本。

    我正在调查 System.ArgumentException: Item has been added at System.Collections.Hashtable.Insert

    堆栈跟踪说明了什么? 您是否要插入 Session 中已经存在的 Hashtable?在这种情况下,您可能会遇到上述竞争条件。

    【讨论】:

    • 如果我尝试在阅读器锁定下设置值怎么办?或者在这种情况下,请求会自动获取写入器锁?我正在调查 System.ArgumentException: Item has been added at System.Collections.Hashtable.Insert 尝试访问会话中的值时会发生这种情况。
    • Joe,非常感谢您花时间回答我的问题。我已经更新了我的问题。还有一篇非常有趣的帖子描述了一个类似(在我看来)的问题。
    猜你喜欢
    • 2012-11-24
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    相关资源
    最近更新 更多