ASP.NET静态变量的生命周期

pau*_*ons 73 c# asp.net static

我在页面类中定义的静态变量中持有一些信息(不在Global.asax中).我只在代码中声明变量,如:

protected static int SomeGlobalUnsecureID;
protected static string SomeGlobalUnsecureString;
Run Code Online (Sandbox Code Playgroud)

并在PageLoad事件中定义变量.例如,我检查数据库中的ID,如果它与SomeGlobalUnsecureID不同,我从其他地方更新SomeGlobalUnsecureID和String,否则保持不变.这在我的应用程序中非常安全.逻辑(即那些数据不安全,每个人都可以访问它们,没问题); 我唯一想做的就是

  1. 无论用户连接如何,都要保持相同的内存量

  2. 当且仅当持久性信息与'memory'中的持久信息不同时才会改变(因为实际读取字符串对我来说非常耗时.

现在,因为我在PageLoad中进行了检查,所以在重新加载的页面中没有问题.然而,我的页面充满了WebMethods,有时我看到静态变量被归零.奇怪的是; 即使静态变量归零,会话仍然处于活动状态(所以 - >没有服务器或应用程序池重启等)

这对我来说真的很奇怪.我假设静态变量将保持其值,直到应用程序(以某种方式)结束.但即使Session没有过期,静态变量也会归零.你有什么建议?使用应用程序变量是更好的选择吗?我在网上看到的所有文件都提出了静态变量而不是应用程序变量,我是否需要声明它们有所不同?

Ari*_*tos 97

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

出于这些原因,如果系统决定重新启动或替换类(.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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

  • @Aristos这可能是一个老问题,但你的答案并不准确.如果一个类变量是静态的,那么你创建和终止这个类的实例数并不重要,只要它的程序集仍然加载到内存中,这个变量仍将保持其值.但是,由于IIS会定期回收托管应用程序,因此某些程序集会被卸载然后再次加载,从而导致静态变量数据丢失.看看[this](http://blogs.msdn.com/b/tess/archive/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles. ASPX) (5认同)

sot*_*otn 16

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

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

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