ASP.NET静态变量的生存期

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (24)

我在页面类(不是Global.asax中)定义的静态变量中保存了一些信息。我只在代码中声明变量如下:

protected static int SomeGlobalUnsecureID;
protected static string SomeGlobalUnsecureString;

并在PageLoad事件中定义变量。例如,我从数据库中检查ID,如果它与SomeGlobalUnsecureID不同,我会更新SomeGlobalUnsecureID和来自其他地方的字符串,否则它们将保持原样。这在我的应用程序中是完全安全的。逻辑(即那些数据不安全,每个人都可以访问它们,没有问题);我唯一想要完成的事情是

  1. 持有相同数量的内存,而不考虑连接的用户。
  2. 如果并且只有当持久信息与“内存”中的信息不同时才进行更改(因为实际上读取字符串对我来说很费时。

现在,由于我在PageLoad中进行了检查,所以在重新加载页面时没有问题。然而,我的页面上充满了WebMethods,有时我看到静态变量是零的。奇怪的是,即使静态变量为零(因此->没有服务器或app.pool,重新启动等等),会话仍然是活动的。

这对我来说真的很奇怪。我假设静态变量将保持其值,直到应用程序(不知怎么地)结束为止。但是,即使会话没有过期,静态变量也是零的。你有什么建议?使用应用程序变量是更好的选择吗?我在网上读过的所有文档都是静态变量而不是应用变量,我是否需要声明它们不同?

提问于
用户回答回答于

静态变量在应用程序域的生命周期中持续存在。因此,导致静态变量“重置”的两件事是重新启动应用程序域或使用新类。对于存储在aspx Page类中的静态变量,当ASP.NET决定将aspx Page重新编译为新类时,可能会失去静态变量,用新的类替换旧的页面类。

由于这些原因,如果系统决定重新启动或替换类(.NET不会终止或卸载正在运行的应用程序域中的类/程序集,那么您的静态变量将重置,因为您正在重新启动或更换新类。适用于App_Code文件夹中的 aspx页面和

如果由于某种原因,ASP.NET将会替换一个类,认为需要重新编译它(请参阅ASP.NET动态编译

您无法防止应用程序域重新启动时丢失静态变量,但您可以尝试避免它从类替换。你可以把你的静态变量放在一个不是aspx页面的类中,它不在App_Code目录下。你可能想把它们放在static class程序的某个地方。

public static class GlobalVariables
{
    public static int SomeGlobalUnsecureID;
    public  static string SomeGlobalUnsecureString;
}

静态变量是每个池,这意味着如果你有2个池来运行你的asp.net站点,你有2个不同的静态变量。(Web花园模式

如果系统以这种方式之一重新启动asp.net应用程序,静态变量将丢失。

  1. 池决定需要重新编译。
  2. 打开app_offline.htm文件
  3. 手动重新启动池
  4. 池已达到定义并重新启动的一些限制。
  5. 出于任何原因你重新启动iis或游泳池。

这个静态变量不是线程安全的,如果你从不同的线程访问它们,你需要使用lock关键字。

由于应用程序重新启动会重置静态,无论如何,如果确实想要保存数据,则应该使用自定义类将数据存储在数据库中。可以存储每个用户的信息会话状态数据库会话状态模式。ASP.NET应用程序状态/变量不会帮助你,因为它们存储在内存中,而不是数据库中,所以它们在应用程序域重新启动时也会丢失。

用户回答回答于

我认为以下两点对于静态变量的生命周期同样重要:

1 - 在应用程序池的高级设置中,选中“回收” - >“常规时间间隔(分钟)”设置。它的默认值是1740,这意味着在每29个小时内,由于应用程序池的回收,静态变量会丢失。该设置用于终止可能的内存泄漏。我不会改变这个设置..

2 - 在应用程序池的高级设置中,选中“Process Model” - >“Idle Time-out(minutes)”设置。它的默认值是20,这意味着在应用程序池中每20分钟不活动,工作进程将被终止/挂起,这会导致您的静态变量丢失。此设置用于在某个时间段内未使用应用程序池时释放资源。您可以将其设置为0以禁用超时。

扫码关注云+社区