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

时间:2012-01-18 23:31:25

标签: c# asp.net static

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

protected static int SomeGlobalUnsecureID;
protected static string SomeGlobalUnsecureString;

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

  1. 无论用户是否连接,都要保留相同数量的内存

  2. 当且仅当持久性信息与中的信息不同时才更改 '记忆'(因为实际读取字符串是耗时的 我

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

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

3 个答案:

答案 0 :(得分:92)

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

由于这些原因,如果系统决定重新启动或替换类(.NET doesn't kill or unload classes/assemblies in a running app domain),那么您的静态变量将重置,因为您正在获得重新启动或替换的新类。这适用于aspx页面和classes in the App_Code folder

如果出于任何原因认为需要重新编译它(see ASP.NET dynamic compilation),ASP.NET将替换一个类。

您无法阻止应用程序域重新启动时丢失静态变量,但您可以尝试从类替换中避免它。您可以将静态变量放在不是aspx页面且不在App_Code目录中的类中。您可能希望将它们放在程序中的static class处。

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

静态变量是每个池,这意味着如果你有两个运行你的asp.net站点的池,你有2个不同的静态变量。 (Web garden mode

如果系统以这种方式重启你的asp.net应用程序,静态变量就会丢失。

  1. 池决定需要重新编译。
  2. 您打开app_offline.htm文件
  3. 您手动重启池
  4. 池已达到您定义的某些限制并重新启动。
  5. 出于任何原因,您重新启动iis或池。
  6. 此静态变量不是线程安全的,如果从不同的线程访问它们,则需要使用 lock 关键字。

    由于应用程序重新启动会重置静态,无论如何,如果您确实要保留数据,则应使用自定义类将数据存储在数据库中。您可以使用Session State将每位用户的信息存储在database session state mode中。 ASP.NET应用程序状态/变量对they are stored in memory, not the database没有帮助,因此它们在应用程序域重启时也会丢失。

答案 1 :(得分:15)

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

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

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

答案 2 :(得分:-7)

静态变量用于存储相同值的所有对象

protected void Page_Load(object sender, EventArgs e)
{
    sss s1, s2;
    s1 = new sss();
    s1.TotalMark = 10;
    s2 = new sss();
    s2.TotalMark = 20;
    sss.SchoolName = "St.Joseph's Hr.Sec.S"; //We can access through class and assign common to all
    s1.PrintData();
    s2.PrintData();
}

public class sss
{
    public static string SchoolName { set; get; }
    public int TotalMark { set; get; }
    public string StudentName{set;get;}
    public void PrintData()
    {
        Console.WriteLine(TotalMark);
        Console.WriteLine(SchoolName);
        Console.WriteLine(StudentName);
    }
}
相关问题