我在页面类中定义的静态变量中持有一些信息(不在Global.asax中)。我只在代码中声明变量,如:
protected static int SomeGlobalUnsecureID;
protected static string SomeGlobalUnsecureString;
并在PageLoad事件中定义变量。例如,我检查数据库中的ID,如果它与SomeGlobalUnsecureID不同,我从其他地方更新SomeGlobalUnsecureID和String,否则保持不变。这在我的应用程序中非常安全。逻辑(即那些数据不安全,每个人都可以访问它们,没问题);我唯一想做的就是
无论用户是否连接,都要保留相同数量的内存
当且仅当持久性信息与中的信息不同时才更改 '记忆'(因为实际读取字符串是耗时的 我
现在,因为我在PageLoad中进行了检查,所以在重新加载的页面中没有任何问题。然而,我的页面充满了WebMethods,有时我看到静态变量被归零。奇怪的是;即使静态变量归零,会话仍然有效(所以>没有服务器或应用程序池重启等)。
这对我来说真的很奇怪。我假设静态变量将保持其值,直到应用程序(以某种方式)结束。但即使Session没有过期,静态变量也会归零。你有什么建议?使用应用程序变量是更好的选择吗?我在网上看到的所有文件都提出了静态变量而不是应用程序变量,我是否需要以不同的方式声明它们?
答案 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应用程序,静态变量就会丢失。
此静态变量不是线程安全的,如果从不同的线程访问它们,则需要使用 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);
}
}