Lebensdauer der statischen ASP.NET-Variable

Ich halte einige Informationen in statischen Variablen, die in der Seitenklasse definiert sind (nicht in Global.asax). Ich deklariere Variable nur in Code wie:

protected static int SomeGlobalUnsecureID; protected static string SomeGlobalUnsecureString; 

Definieren Sie die Variable im PageLoad-Ereignis. Zum Beispiel überprüfe ich die ID aus der database, wenn sie sich von SomeGlobalUnsecureID unterscheidet, aktualisiere ich SomeGlobalUnsecureID und String von woanders, ansonsten lasse sie unverändert. Dies ist absolut sicher in meiner App. Logik (dh diese Daten sind nicht sicher, jeder kann darauf zugreifen, kein Problem); Ich möchte nur etwas erreichen

  1. Halten Sie die gleiche Menge an Speicher unabhängig von angeschlossenen Benutzern

  2. Ändern Sie, wenn und nur wenn sich persistente Informationen von denen im ‘Speicher’ unterscheiden (weil das Lesen der Zeichenfolge für mich zeitaufwendig ist).

Jetzt, seit ich den PageLoad einchecke, habe ich keine Probleme mit neu geladenen Seiten. Meine Seite ist jedoch voll von WebMethods, und manchmal sehe ich, dass die statischen Variablen auf Null gesetzt sind. Und der seltsame Teil ist; die Sitzung ist immer noch aktiv, selbst wenn die statischen Variablen auf Null gesetzt sind (also-> kein Server- oder App-Pool-Neustart usw.)

Das ist wirklich seltsam für mich. Ich nehme an, dass die statische Variable ihren Wert behält, bis die Anwendung (irgendwie) endet. Aber selbst die Sitzung lief nicht ab, die statische Variable wird auf Null gesetzt. Was schlagen Sie vor? Ist die Verwendung von Anwendungsvariablen eine bessere Wahl? Alle Dokumente, die ich im Internet gelesen habe, schlagen statische Variablen anstelle von Anwendungsvariablen vor. Muss ich sie irgendwie anders deklarieren?

Statische Variablen bleiben für die Lebensdauer der App-Domäne bestehen. Die zwei Dinge, die dazu führen, dass Ihre statischen Variablen zurückgesetzt werden, sind der Neustart einer App-Domäne oder die Verwendung einer neuen class. In Ihrem Fall mit statischen Variablen, die in einer aspx Page-class gespeichert sind, verlieren Sie möglicherweise die statischen Variablen, wenn ASP.NET beschließt, die aspx-Page in eine neue class umzuwandeln und die alte Seitenklasse durch die neue zu ersetzen.

Aus diesen Gründen werden die statischen Variablen zurückgesetzt, wenn das System entscheidet, die class neu zu starten oder zu ersetzen ( .NET führt keine classn / Assemblys in einer aktiven App-Domäne aus oder aus ). Sie erhalten dann eine neue class mit dem Neustart oder der Ersetzung. Dies gilt sowohl für aspx-Seiten als auch für classn im Ordner App_Code

ASP.NET ersetzt eine class, wenn sie aus irgendeinem Grund denkt, dass sie neu kompiliert werden muss ( siehe dynamische ASP.NET-Kompilierung ).

Sie können den Verlust statischer Variablen beim Neustart einer App-Domäne nicht verhindern, aber Sie können versuchen, den Austausch von classn zu vermeiden. Sie könnten Ihre statischen Variablen in eine class einfügen, die keine aspx-Seite ist und nicht im Verzeichnis App_Code ist. Vielleicht möchten Sie sie in einer static class irgendwo in Ihrem Programm platzieren.

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

Die statischen Variablen sind pro Pool, das heißt, wenn Sie 2 Pools haben, die Ihre asp.net-Site ausführen, haben Sie 2 verschiedene statische Variablen. ( Web-Garten-Modus )

Die statischen Variablen gehen verloren, wenn das System Ihre asp.net-Anwendung auf diese Weise neu startet.

  1. Der Pool entscheidet, dass eine Neukompilierung erforderlich ist.
  2. Sie öffnen die Datei app_offline.htm
  3. Sie führen einen manuellen Neustart des Pools durch
  4. Der Pool erreicht einige von Ihnen definierte Grenzen und startet neu.
  5. Aus irgendeinem Grund starten Sie die IIS oder den Pool neu.

Diese statischen Variablen sind nicht Thread-sicher, und Sie müssen das Schlüsselwort ” lock” verwenden, wenn Sie von verschiedenen Threads darauf zugreifen.

Da ein App-Neustart Ihre Statik zurücksetzt, egal was passiert, sollten Sie die Daten wirklich in einer database speichern, indem Sie benutzerdefinierte classn verwenden. Sie können Informationen pro Benutzer im Sitzungsstatus mit einem databasesitzungsstatusmodus speichern . ASP.NET-Anwendungsstatus / -Variablen werden Ihnen nicht weiterhelfen, da sie im Speicher und nicht in der database gespeichert sind , sodass sie beim Neustart der App-Domäne verloren gehen.

Ich denke, dass die folgenden zwei Punkte auch für die Lebensdauer von statischen Variablen wichtig sind:

1 – Überprüfen Sie in den erweiterten Einstellungen Ihres Anwendungspools die Einstellung “Recycling” -> “Reguläres Zeitintervall (Minuten)”. Der Standardwert ist 1740, was bedeutet, dass in 29 Stunden Ihre statischen Variablen aufgrund des Recyclings Ihres Anwendungspools verloren gehen. Diese Einstellung wird zur Beendigung möglicher Speicherlecks verwendet. Ich würde diese Einstellung nicht ändern.

2 – Überprüfen Sie in den erweiterten Einstellungen Ihres Anwendungspools die Einstellung “processmodell” -> “Leerlauf-Zeitüberschreitung (Minuten)”. Der Standardwert ist 20, was bedeutet, dass die Arbeitsprozesse in jedem 20 Minuten Inaktivität in Ihrem Anwendungspool beendet / ausgesetzt werden, was dazu führt, dass Ihre statischen Variablen verloren gehen. Diese Einstellung wird zum Freigeben von Ressourcen verwendet, wenn der Anwendungspool in einer bestimmten Zeit nicht verwendet wird. Sie können es auf 0 setzen, um das Zeitlimit zu deaktivieren.

Statische Variable wird verwendet, um alle Objekte für denselben Wert zu speichern

 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); } }