ASP.NET InProc会话如何工作?只读会话是否可以实现竞争条件?

时间:2014-10-10 11:01:01

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

我想澄清一下ASP.NET会话的一些细节。我使用ASP.NET MVC 3.
假设我有一个标有[SessionState(SessionStateBehavior.ReadOnly)]属性的控制器 - 所以它使用只读会话 会话处于InProc模式 根据{{​​3}},对此控制器的请求获取读锁定,无法更新会话 如果他们试图更新会话值,我想了解这些请求(在一个公共会话中)是否仍然可以 ? 这些请求使用相同的会话数据结构,而不是单独的副本,对吧? 如何更新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"]即可。

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

1 个答案:

答案 0 :(得分:2)

只要您只在Session中存储不可变对象,就不存在竞争条件的风险。可以同时保持多个读锁定,但在保持写锁定时无法获取读锁定,并且在保持读锁定时无法获取写锁定。

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

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

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

但是你不会被阻止试图改变Session中对象的状态。

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

更新以回应评论

  

如果我尝试在读取器锁定下设置值

,该怎么办?

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

  

我正在调查System.ArgumentException:Item已经添加到System.Collections.Hashtable.Insert

堆栈跟踪说什么? 您是否插入了Session中已存在的Hashtable?在这种情况下,您可以获得如上所述的竞争条件。