【问题标题】:What is really stored in Session in ASP.NET?ASP.NET 中的 Session 中真正存储了什么?
【发布时间】:2008-12-02 19:30:59
【问题描述】:

我们正在尝试决定如何处理跨回发的对象持久性,以避免在每个请求中从数据库中获取数据,并且我倾向于使用 Session(它是一个 Intranet 应用程序,不会有成千上万的用户),但这是因为我怀疑那里只存储了对真实对象的引用......

有人知道这是不是真的吗?

我一直被教导不要过度使用会话对象,但如果它以这种方式工作,那真的不是什么大问题...

这里的会话中真正存储了什么:

Session["myKey"] = myObject;

实际的序列化对象,还是它的引用?

【问题讨论】:

    标签: asp.net session persistence postback


    【解决方案1】:

    我试过这个:

    我创建了一个类并将其实例存储在会话中(会话状态模式:InProc)。实例位于 aspnet_wp.exe proc 中。

    然后,我将会话状态更改为 SQL Server(仍然没有 [Serializable] 属性),然后出现以下错误。

    无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许使用不可序列化对象或 MarshalByRef 对象。

    因此,inProc 会话状态没有序列化。

    干杯... 马丁

    【讨论】:

      【解决方案2】:

      ASP.NET 默认创建一个存储在 cookie 中的 GUID(但您可以指定使用查询字符串)来识别用户。默认情况下,与该 cookie 关联的对象存储在 IIS 进程内的服务器上。

      您还可以创建自定义会话对象存储(会话状态存储提供程序),例如,如果您想将会话对象保持在进程之外。

      更多信息在这里:

      http://msdn.microsoft.com/en-us/library/ms178587.aspx

      但要真正回答你的问题......

      开箱即用,假设会话存储仅存储对对象的引用是正确的。

      不过,我相信您可以在 web.config 中指定会话功能的存储行为,也可以实现序列化。三种模式:

      • InProc - 会话作为活动对象保存在 Web 服务器 (aspnet_wp.exe) 中。在 web.config 中使用“cookieless”配置将 sessionId “mung”到 URL 上(也解决 cookie/domain/path RFC 问题!)
      • StateServer - 会话序列化并存储在内存中的单独进程 (aspnet_state.exe) 中。状态服务器可以在另一台机器上运行
      • SQLServer - 会话序列化并存储在 SQL Server 中

      以上来自:http://www.eggheadcafe.com/articles/20021016.asp

      【讨论】:

        【解决方案3】:

        这取决于您使用的会话,如果您使用 inproc 会话,您确实在会话中存储了引用,但是在引用它时它只是一个指向对象的链接,它将整个对象保留在进程内存中,所以当你设计您的应用程序非常希望知道每个用户将拥有多少数据以及每小时将拥有多少活跃用户。如果在 proc session 中使用,则进程内存中的对象不会被序列化,但如果在 out of proc session 中使用,它会被序列化,它可能会对性能产生影响。

        我觉得在这里你可以找到很好的overview of session and cache

        【讨论】:

        • 我也是这样想的,有没有办法测试一下?
        • 您可以使用内存分析器来检查此行为,但我想强调在进程内会话中存储对象会增加内存消耗,如果您打算在不同用户之间共享数据,最好在缓存中使用 .net 构建
        • 什么内置缓存? HttpResponse.Cache 由所有用户共享——就像 Application 对象缓存一样。
        • 你可以看看我添加的链接
        【解决方案4】:

        有大量文章和博客文章抱怨在会话变量中存储复杂对象(技术上存储对所述对象的引用)的使用。一般来说,我认为会话变量是魔鬼的工作,并尽我所能避免它们。

        也就是说,对于一个部署在 Intranet 的应用程序,开发人员完全了解 Juan Manuel 所描述的过度使用会话会话的可扩展性影响,我已经做了很多次并且取得了巨大的成功。是的,会话可以回收,但这是一个不寻常的边缘情况——这种情况发生的频率不足以影响具有合理会话超时的浏览器应用程序。

        我会说至少在开始时按照您建议的方式构建应用程序,Juan Manuel。但是,您要从会话中保存和获取对象(可能使用包装类)的地方松手,这样如果应用程序需要,以后可以轻松更改。

        【讨论】:

        • 是的,我正计划使用包装类。感谢您的反馈
        【解决方案5】:

        请务必记住,In-Proc Session 数据相当脆弱……这意味着当您最需要它时,它可能并不存在。如果工作进程因任何原因回收,它就消失了。

        【讨论】:

        • 没关系...我会再去取它...目标是避免每次都这样做
        【解决方案6】:

        我知道您现在没有太多性能问题,会话可能会正常工作;但是,还有其他方法可以在回发中维护状态或携带数据。

        如果您尝试在同一页面的回发中保留数据,那么我建议您改用 ViewState。请注意,存储在 ViewState 中的数据是序列化的,您想要持久化的任何对象都必须实现 ISerializable。

        【讨论】:

        • 嗯......这只是你所说的更糟糕,它只适用于同页回发......此外,对象必须在每个回传中来回移动。不过还是谢谢
        • 你是对的,不清楚你是想在一个页面内保持状态还是在不同的页面上进行。如果是这种情况,如果工作进程回收,您将受益于不会丢失您的对象。祝你好运!
        猜你喜欢
        • 2018-06-10
        • 2017-12-16
        • 2023-03-30
        • 1970-01-01
        • 2021-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-09
        相关资源
        最近更新 更多