31

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

  1. 任何类型的数据都可以存储在 Session 中。然而,它必须被强制转换。但是静态字段只接受具有正确数据类型的数据。
  2. 会话变量将在一定时间后过期,这是我们在许多情况下需要的行为。

除了上述之外,还有什么其他原因我不应该使用静态字段来存储数据并使其随处可用?

4

4 回答 4

44

不,为此使用静态变量不是可行的方法:

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

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

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

如果您可以使用负载平衡让所有用户访问同一台服务器,并且如果您不介意在 AppDomain 被回收1或服务器关闭时丢失会话,则可以将其保存在内存中,由会话 ID 键入... 不过要小心。


1 ASP.NET 中可能有一些机制可以解决这个问题,将会话信息从一个 AppDomain 传播到另一个 AppDomain - 我不确定

于 2013-02-06T07:13:27.067 回答
13

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

  • 会话可以在进程外使用(对于负载平衡很重要)
  • 会话可以更持久,因为它的进程外能力。
  • 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"];
    }
}

也可以看看:

于 2013-02-06T07:12:04.133 回答
9

你忘了一件事(我想)

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

因此,对于您的“用户角色”场景,我希望得到有趣的结果;)

于 2013-02-06T07:12:17.923 回答
6

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

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

会话可以移出进程并在网络场中共享。

即使您的应用服务器崩溃,也会存在 Out of proc 会话。

于 2013-02-06T07:12:54.553 回答