Freigeben über


Anwendungszustand

Um Informationen innerhalb der Anwendung freizugeben, verwenden Sie die HttpApplicationState-Klasse, auf die am häufigsten über die Application-Eigenschaft des HttpContext-Objekts zugegriffen wird. Diese Klasse stellt ein Schlüssel/Wert-Wörterbuch mit Objekten bereit, mit deren Hilfe sowohl .NET Framework-Objekte als auch skalare Werte gespeichert werden können, die sich auf mehrere Webanforderungen von mehreren Clients beziehen.

Dieses Thema enthält folgende Informationen: Übersicht über den Anwendungszustand, Verwendungsweise des Anwendungszustands, Einführung in Anwendungszustandsauflistungen und Synchronisierung des Anwendungszustands.

Übersicht über den Anwendungszustand

Eine ASP.NET-Anwendung ist die Summe aller Dateien, Seiten, Handler, Module und Codezeichenfolgen in einem bestimmten virtuellen Verzeichnis sowie den zugehörigen Unterverzeichnissen, die Benutzer über die Hierarchie dieses virtuellen Verzeichnisses anfordern können.

Wenn Sie z. B. eine Anwendung entwickeln, die den Investitionsvorteil für das firmeneigene Intranet berechnet, könnten Sie sie in einem virtuellen Verzeichnis mit dem Namen \Invest auf einem Webserver veröffentlichen. Die Verzeichnisstruktur für eine derartige Anwendung könnte z. B. wie folgt lauten:

\Invest

   \bin

   \image

   \xml

Wenn ein Client erstmalig eine URL-Ressource aus dem Namespace des virtuellen Verzeichnisses einer bestimmten ASP.NET-Anwendung anfordert, wird eine Instanz der HttpApplicationState-Klasse erstellt. Dies trifft auf alle auf dem Computer gespeicherten Webanwendungen zu. Auf diese pro Anwendung erstellte Instanz wird über eine HttpContext-Eigenschaft namens Application zugegriffen. Jedes HttpModule und jeder HttpHandler, z. B. eine ASP.NET-Seite, hat Zugriff auf eine kontextspezifische Instanz und kann daher während einer gegebenen Webanforderung auch auf die Application-Eigenschaft zugreifen.

ASP.NET bietet die folgende Unterstützung für den Anwendungszustand:

  • Eine benutzerfreundliche Zustandsverwaltungsfunktion, die mit früheren ASP-Versionen kompatibel ist, mit allen von .NET unterstützten Sprachen verwendet werden kann und auch Kompatibilität mit anderen .NET Framework-APIs bietet.
  • Ein Anwendungszustandswörterbuch, das allen, innerhalb einer Anwendung ausgelösten Anforderungshandlern zur Verfügung steht. Anders als bei Internet-Informationsdiensten (IIS) und früheren Versionen von ASP, in denen nur über Seiten auf den Anwendungszustand zugegriffen werden konnte, sind alle Instanzen von IHttpHandler und IHttpModule in der Lage, globale Variablen im Wörterbuch zu speichern und daraus abzurufen.
  • Ein einfacher, intuitiver Synchronisierungsmechanismus, der Entwicklern die problemlose Koordination gleichzeitiger Zugriffe auf Variablen ermöglicht, die im Anwendungszustand gespeichert sind.
  • Anwendungszustandswerte, auf die nur über Code zugegriffen werden kann, der im Kontext der ursprünglichen Anwendung ausgeführt wird. Andere im System ausgeführte Anwendungen können weder auf die Werte zugreifen noch diese ändern.

Am häufigsten wird mit Hilfe der Application-Eigenschaft des Page-Objekts auf den Anwendungszustand zugegriffen.

Verwenden des Anwendungszustands

Anwendungszustandsvariablen stellen tatsächlich globale Variablen für eine bestimmte ASP.NET-Anwendung dar. Genauso wie Entwickler von clientseitigen Anwendungen sollten sich ASP.NET-Programmierer stets der Konsequenzen bewusst sein, die das Speichern eines Elements als globale Variable hat.

Die folgenden Punkte sind in diesem Kontext von besonderer Bedeutung:

  • Auswirkungen, die das Speichern eines Elements im Anwendungszustand auf den Arbeitsspeicher hat. Der durch im Anwendungszustand gespeicherte Variablen belegte Speicherplatz wird erst freigegeben, wenn die Variable entweder entfernt oder ersetzt wird. Dies steht im Gegensatz zu einer einzelnen Webseite, bei der alle Ressourcen aufgelöst werden, nachdem eine Webanforderung abgeschlossen ist. Selten verwendete 10 MB-Recordsets dauerhaft im Anwendungszustand zu halten, stellt beispielsweise nicht die beste Verwendungsmöglichkeit für Systemressourcen dar. Für dieses extreme Beispiel lassen sich bessere Lösungen finden, indem Sie den ASP.NET-Cache verwenden.
  • Auswirkungen, die die Speicherung und der Zugriff auf eine globale Variable innerhalb einer Multithread-Serverumgebung auf Parallelität und Synchronisierung hat. Mehrere Threads innerhalb einer Anwendung können gleichzeitig auf Werte zugreifen, die im Anwendungszustand gespeichert sind. Sie sollten stets darauf achten, dass ein Objekt im Gültigkeitsbereich der Anwendung, das auf dem Freethreadingmodell basiert, integrierte Synchronisierungsunterstützung umfasst. Alle benutzerdefinierten Objekte, die die Common Language Runtime zum Ziel haben, basieren auf diesem Modell. Verfügt ein Objekt im Gültigkeitsbereich der Anwendung nicht über das Freethreadingmodell, muss sichergestellt werden, dass das Objekt im Code von expliziten Synchronisierungsmethoden eingeschlossen ist, um Deadlocks, Geschwindigkeitsprobleme und Zugriffsverletzungen zu vermeiden.
  • Auswirkungen, die die Speicherung und der Zugriff auf eine globale Variable innerhalb einer Multithreadserverumgebung auf die Skalierbarkeit hat. Bei jedem Versuch, in eine Datei zu schreiben oder sie zu aktualisieren, sollten Sperren verwendet werden. Sperren zum Schutz globaler Ressourcen sind selbst als global anzusehen, und Code, der in mehreren Threads ausgeführt wird, die auf globale Ressourcen zugreifen, wird schließlich an diesen Sperren scheitern. Dadurch werden die Arbeitsthreads vom Betriebssystem blockiert, bis die Sperre verfügbar wird. In hoch ausgelasteten Serverumgebungen kann diese Blockierung dazu führen, dass zahlreiche Threads im System nicht effizient genutzt werden. Auf Mehrprozessorsystemen kann es dazu kommen, dass Prozessoren nicht optimal ausgelastet werden (da alle Threads für einen Prozessor beim Warten auf eine freigegebene Sperre theoretisch blockiert werden können) und dass die gesamte Skalierbarkeit erheblich beeinträchtigt wird.
  • Auswirkungen, die im Anwendungszustand gespeicherte Informationen auf den Lebenszyklus haben. Die .NET Framework-Anwendungsdomäne oder der Prozess, der als Host für eine .NET-basierte Anwendung fungiert, kann jederzeit während der Anwendungsausführung aufgelöst und zerstört werden (und zwar als Folge von Abstürzen, Codeaktualisierungen, geplanten Prozessneustarts usw.). Da im Anwendungszustand gespeicherte Daten nicht dauerhaft sind, gehen sie verloren, wenn der Host, in dem sie enthalten sind, zerstört wird. Wenn der Zustand von diesen Fehlertypen unbeeinflusst bleiben soll, sollte er in einer Datenbank oder auf einem anderen permanenten Speichermedium gespeichert werden.
  • Innerhalb einer Webfarm (in der eine Anwendung von mehreren Servern gehostet wird) oder eines Webgartens (in dem eine Anwendung von mehreren Prozessen auf demselben Server gehostet wird) ist der Anwendungszustand nicht freigegeben. Im Anwendungszustand gespeicherte Variablen beider Szenarien werden nur von dem jeweiligen Prozess als global betrachtet, in dem die Anwendung ausgeführt wird. Jeder Anwendungsprozess kann verschiedene Werte aufweisen. Daher kann der Anwendungszustand nicht dazu verwendet werden, z. B. in Webfarm- und Webgartenszenarien, eindeutige Werte zu speichern oder globale Zähler zu aktualisieren.

Trotz dieser Einschränkungen können mit Überlegung entworfene Variablen auf Anwendungsebene ein leistungsstarkes Werkzeug in Webanwendungen darstellen. Sie können Informationen einmalig (oder gelegentlich) laden und berechnen lassen und anschließend mit Hilfe des Anwendungszustands zwischenspeichern, um in späteren Webanforderungen schnelle Speicherzugriffe zu ermöglichen.

In einer Börsenwebsite werden beispielsweise tagsüber alle 5 Minuten umfangreiche Kursinformationen (z. B. 40 MB Daten) aus einer Datenbank abgerufen und anschließend im Anwendungszustand zwischengespeichert. Dort kann in allen nachfolgenden Suchanforderungen auf die Daten zugegriffen werden. Daraus resultiert bei jeder Anforderung eine dramatische Leistungssteigerung, da eingehende Anforderungen weder prozess- oder computerübergreifend ausgeführt werden müssen noch Datenbank-Roundtrips erforderlich sind. Andererseits kann die Nutzung des Caches für umfangreiche, flüchtige Datenblöcke eine bessere Ressourcennutzung bedeuten.

Anwendungszustandsauflistungen

Die HttpApplicationState-Klasse stellt zwei Zustandsauflistungen bereit: Contents und StaticObjects.

Durch die Contents-Auflistung werden alle Variablenelemente zur Verfügung gestellt, die der Anwendungszustandsauflistung direkt über den Code hinzugefügt wurden. Beispiel:

'  Visual Basic code from within a page, a handler, or Global.asax.
Application("Message") = "MyMsg"
Application("AppStartTime") = Now
[C#]
// C# code from within a page, a handler, or Global.asax.
Application["Message"] = " MyMsg";
Application["AppStartTime"] = DateTime.Now;

Um Kompatibilität mit früheren ASP-Versionen zu gewährleisten, kann auf diese Variablen auch mit der Contents-Eigenschaft des Anwendungsobjekts zugegriffen werden, wie im folgenden Beispiel dargestellt.

' Visual Basic code from within a page, a handler, or Global.asax.
Application.Contents("Message") = " MyMsg"
Application.Contents("AppStartTime") = Now
[C#]
// Visual Basic code from within a page, a handler, or Global.asax.
Application.Contents["Message"] = " MyMsg";
Application.Contents["AppStartTime"] = DateTime.Now;

Die StaticObjects-Auflistung stellt alle Variablenelemente bereit, die der Anwendungszustandsauflistung über <object runat="server">-Tags mit dem Gültigkeitsbereich application in der Datei Global.asax hinzugefügt wurden. Beispiel:

' Global.asax definition.
<object runat="server" scope="application" ID="MyInfo" PROGID="MSWC.MYINFO">
</OBJECT>

Objekte können der StaticObjects-Auflistung nur aus einer ASP.NET-Anwendung heraus hinzugefügt werden. Beim Versuch, Objekte direkt über den Code hinzuzufügen, wird eine NotSupportedException-Ausnahme ausgelöst.

Beachten Sie, dass der .NET-Seitencompiler automatisch Memberverweise in alle innerhalb der StaticObjects-Auflistung gespeicherten Objekte einfügt, wenn die Seite kompiliert wird. Auf diese Weise können Entwickler, wenn die Seite angefordert wird, auf diese Anwendungsobjekte zugreifen, ohne auf die Application-Auflistung zu verweisen. Beispiel:

<html>
   </body>
      Application Level Title: <%= MyInfo.Title %>
   <body>
</html>

Synchronisieren des Anwendungszustands

Mehrere Threads innerhalb einer Anwendung können gleichzeitig auf Werte zugreifen, die im Anwendungszustand gespeichert sind. Folglich muss bei der Erstellung von Elementen, die auf Anwendungszustandswerte zugreifen müssen, immer sichergestellt werden, dass das Anwendungszustandsobjekt auf dem Freethreadingmodell basiert und eine eigene interne Synchronisierung durchführt bzw. dass manuelle Synchronisierungsschritte ausgeführt werden, um zu verhindern, dass Geschwindigkeitsprobleme, Deadlocks und Zugriffsverletzungen entstehen.

Die HttpApplicationState-Klasse stellt mit Lock und Unlock zwei Methoden bereit, die bewirken, dass jeweils nur ein Thread auf Anwendungszustandsvariablen zugreifen kann.

Durch den Aufruf von Lock für das Application-Objekt blockiert ASP.NET Versuche des in anderen Arbeitsthreads ausgeführten Codes, auf Daten im Anwendungszustand zuzugreifen. Die Blockierung dieser Threads wird erst wieder aufgehoben, wenn durch den Thread, durch den Lock aufgerufen wurde, die entsprechende Unlock-Methode für das Application-Objekt aufgerufen wird.

Das folgende Codebeispiel veranschaulicht die Verwendung von Sperren, um Geschwindigkeitsprobleme zu verhindern.

' Visual Basic code from within a page, a handler, or Global.asax.
Application.Lock()
Application("SomeGlobalCounter") = _
   CType(Application("SomeGlobalCounter"), Integer) + 1
Application.UnLock()
[C#]
// C# code from within a page, a handler, or Global.asax.
Application.Lock();
Application["SomeGlobalCounter"] =
   (int)Application["SomeGlobalCounter"] + 1;
Application.UnLock();

Wenn Sie Unlock nicht explizit aufrufen, wird die Sperre von .NET Framework automatisch entfernt, wenn die Anforderung abgeschlossen oder das Zeitlimit überschritten ist bzw. wenn während der Anforderungsausführung ein nicht behandelter Fehler auftritt, was dazu führt, dass die Anforderung fehlschlägt. Diese automatische Aufhebung der Sperre verhindert, dass Deadlocks in der Anwendung auftreten.

Siehe auch

ASP.NET-Zustandsverwaltung | ASP.NET-Anwendungen