静态字段与会话变量

时间:2013-02-06 07:09:30

标签: c# asp.net .net session-variables static-members

到目前为止,我一直在使用Session将一些变量从一个页面传递到另一个页面。例如用户角色。当用户登录到Web应用程序时,用户的角色ID保留在Session中,并且在应用程序的不同部分检查该角色。我最近开始考虑为什么不使用静态成员。我可以在静态字段中存储相同的信息,并在我的应用程序的任何地方轻松访问它(包括静态字段所在的命名空间的任何位置。)我知道使用Session变量有时会派上用场,这样:

  1. 任何类型的数据都可以存储在Session中。然而,它必须被转换。但静态字段仅接受具有正确数据类型的数据。
  2. 会话变量将在一段时间后过期,这是我们在许多情况下需要的行为。
  3. 除了上述内容之外,还有其他任何原因我不应该使用静态字段来存储数据并让它随处可用吗?

4 个答案:

答案 0 :(得分:37)

不,使用静态变量是的方法:

  • 如果您的AppDomain被回收,则所有静态变量都将被“重置”
  • 静态变量不会水平扩展 - 如果您对应用程序进行负载平衡,那么命中一个服务器然后另一个服务器的用户将无法在第一个服务器的静态变量中看到数据存储
  • 最重要的是,静态变量将由所有访问该服务器共享...它根本不会基于每个用户...而根据您的描述,您不会不希望用户X看到用户Y的信息。

从根本上说,您有两种选择来传播应用程序周围的信息:

  • 保持客户端,因此每个请求都会提供前面步骤中的信息。 (这可能会因大量信息而变得难以处理,但对于简单的情况可能会有用。)
  • 保持服务器端,理想情况下以某种持久性方式(例如数据库)与客户端提供会话标识符。

如果,您可以使用负载平衡来保持所有用户访问同一服务器,而 if 时,您不介意在AppDomain被回收时丢失会话< sup> 1 或服务器停机,你可以把它保存在内存中,用会话ID键入......但要小心。


1 ASP.NET中可能存在一些机制可以将其从一个AppDomain传播到另一个AppDomain - 我不确定

答案 1 :(得分:12)

它们是两个非常不同的东西。

  • 会话可以在进程外使用(对负载平衡很重要)
  • 由于其处理过程能力,会话可以更持久。
  • ASP.Net自动管理会话并发。
  • 需要手动同步对静态变量的访问。
  • 静态对整个应用域都是全局的。如果为一个用户设置静态字段/属性的值,则所有用户都将获得相同的值。不是您的方案中所需的行为。
  

任何类型的数据都可以存储在Session中。然后必须进行铸造   但是,静态字段只接受具有正确数据类型的数据。

使用辅助类抽象Session值通常很有帮助。这可以提高可测试性,还允许您强烈地键入属性并在类的内部执行强制转换。

示例:

public List<int> UserRoles
{
    get
    {
        // optionally check that the value is indeed in session, otherwise this 
        // will throw
        return (List<int>)Session["UserRoles"];
    }
}

另见:

答案 2 :(得分:9)

你忘了一件事(我想)

静态数据对于应用程序的所有用户都是相同的,而会话是“每个用户”。

因此,对于您的“用户角色”方案,我希望有趣的结果;)

答案 3 :(得分:6)

静态字段将在所有用户之间共享 在Web环境中,您将有多个线程一起运行。

更新任何静态成员都需要适当的并发控制。如果错了,这会显着降低您的网站效果。

会话可以移出流程并在Web场中共享。

即使您的应用服务器崩溃,也会存在进程中的会话。