我们正在尝试决定如何处理跨回发的对象持久性,以避免在每个请求中从数据库中获取数据,并且我倾向于使用 Session(它是一个 Intranet 应用程序,不会有成千上万的用户),但是这是因为我怀疑只有对真实对象的引用存储在那里......
如果这是真的,有人知道事实吗?
我一直被教导不要过度使用会话对象,但如果它以这种方式工作,那真的不是一个大问题......
真正存储在会话中的内容:
Session["myKey"] = myObject;
实际的序列化对象,还是它的引用?
我们正在尝试决定如何处理跨回发的对象持久性,以避免在每个请求中从数据库中获取数据,并且我倾向于使用 Session(它是一个 Intranet 应用程序,不会有成千上万的用户),但是这是因为我怀疑只有对真实对象的引用存储在那里......
如果这是真的,有人知道事实吗?
我一直被教导不要过度使用会话对象,但如果它以这种方式工作,那真的不是一个大问题......
真正存储在会话中的内容:
Session["myKey"] = myObject;
实际的序列化对象,还是它的引用?
我试过这个:
我已经创建了一个类并将它的一个实例存储在会话中(会话状态模式:InProc)。实例位于 aspnet_wp.exe proc 中。
然后,我将会话状态更改为 SQL Server(仍然没有 [Serializable] 属性),然后出现以下错误。
无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许不可序列化的对象或 MarshalByRef 对象。
因此,inProc 会话状态没有序列化。
干杯...马丁
ASP.NET 默认创建一个存储在 cookie 中的 GUID(但您可以指定使用查询字符串)来识别用户。默认情况下,与该 cookie 关联的对象存储在 IIS 进程内的服务器上。
您还可以创建自定义会话对象存储(会话状态存储提供程序),例如,如果您想将会话对象保持在进程之外。
更多信息在这里:
http://msdn.microsoft.com/en-us/library/ms178587.aspx
但要真正回答你的问题......
开箱即用,假设会话存储仅存储对对象的引用是正确的。
虽然,我相信您可以在 web.config 中指定会话功能的存储行为,以实现序列化。3种模式:
这取决于您使用的会话,如果您使用 inproc 会话,您确实在会话中存储了引用,但是在引用它时它只是一个指向对象的链接,它将整个对象保留在进程内存中,所以当你设计你的应用程序时非常希望知道每个用户将拥有多少数据以及每小时将拥有多少活跃用户。如果在 proc session 中使用,则 proccess 内存中的对象不会被序列化,但如果在 out of proc session 中使用,它会被序列化,它可能会对性能产生影响。
我认为在这里您可以找到非常好的会话和缓存概述
有大量文章和博客文章哀叹在会话变量中存储复杂对象(技术上存储对所述对象的引用)的使用。一般来说,我认为会话变量是魔鬼的工作,并尽我所能避免它们。
也就是说,对于一个部署在 Intranet 的应用程序,开发人员完全了解 Juan Manuel 所描述的过度使用会话会话的可伸缩性影响,我已经这样做了很多次并且取得了巨大的成功。是的,会话可以回收,但这是一个不寻常的边缘情况——这种情况发生的频率不足以影响具有合理会话超时的浏览器应用程序。
我会说按照您建议的方式构建应用程序,Juan Manuel,至少一开始是这样。但是将您保存和从会话中获取对象的地方(可能使用包装器类)松鼠,这样如果应用程序需要,以后很容易更改。
重要的是要记住,In-Proc Session 数据相当脆弱……这意味着当您最需要它时它可能不存在。如果工作进程因任何原因回收,它就消失了。
我知道您现在没有太多性能问题,会话可能会正常工作;但是,还有其他方法可以在回发中维护状态或携带数据。
如果您尝试在同一页面的回发中保留数据,那么我建议您改用 ViewState。请注意,存储在 ViewState 中的数据是序列化的,您想要持久化的任何对象都必须实现 ISerializable。