我们在 ASP.NET Web 应用程序中得到随机 System.NullReferenceException。
我们正在使用 inproc session 状态。
堆栈跟踪:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Specialized.NameObjectCollectionBase.BaseRemove(String name)
at System.Web.SessionState.SessionStateItemCollection.Remove(String name)
at System.Web.SessionState.HttpSessionStateContainer.Remove(String name)
at System.Web.UI.SessionPageStatePersister.Save()
at System.Web.UI.Page.SaveAllState()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
问题似乎来自我们已经像这样覆盖的 Page.PageStatePersister 属性。
protected override PageStatePersister PageStatePersister {
get {
return new SessionPageStatePersister(Page);
}
}
Reflector 显示 SessionPageStatePersister 在内部调用了 Session.Remove。
当直接在 Page 上调用 Session.Remove 时,我们会得到类似的随机 NullReferenceException。
相关堆栈跟踪:
---> System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Specialized.NameObjectCollectionBase.BaseRemove(String name)
at System.Web.SessionState.SessionStateItemCollection.Remove(String name)
at System.Web.SessionState.HttpSessionStateContainer.Remove(String name)
at System.Web.SessionState.HttpSessionState.Remove(String name)
at PERH.WebFramework.Bases.PageBase.OnPreInit(EventArgs e) in
任何想法,什么可能导致这些异常?
环境:
IIS6、Windows Server 2003 64 位、.net Framework 3.5
最佳答案
当同时处理同一用户(来自同一 session ID)的请求时,可能会出现此问题。
这是因为 System.Web.SessionState.SessionStateItemCollection
删除条目时不检查条目是否为空。
在 System.Web.SessionState.SessionStateItemCollection.Remove(string name)
在私有(private)集合上设置锁的方法_serializedItems
这样 Remove 操作是线程安全的。然而,这个私有(private)集合在添加操作期间不会被锁定。考虑到 _serializedItems
表现为一个调整大小的数组(当条目数 >= 其容量的 1/2 时,容量会加倍并且新条目填充为空值)并发添加可能会导致空值保留在集合中间的情况。
条目只会从 [0;条目数] _serializedItems
的范围收藏。删除条目时,它的 Key
属性在没有空检查的情况下被访问。因此,如果 空 集合中间的条目被删除 NullReferenceException
被类型转换。
默认情况下,所有具有相同 session ID 的请求都会按顺序处理,除非 System.Web.Configuration.PagesSection.EnableSessionState
显式设置为 ReadOnly
.
在这种情况下,任何涉及将值添加到 System.Web.SessionState.HttpSessionState
中的操作(内部使用 System.Web.SessionState.HttpSessionStateContainer
而内部使用 System.Web.SessionState.SessionStateItemCollection
)应正确锁定以确保线程安全。
关于ASP.NET 应用程序从 Session.Remove 实现中引发 System.NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14249269/