Sind statische Klassen auf einer ASP.NET-Website für jede Webanforderung eindeutig oder werden sie bei Bedarf instanziiert und bei jeder Entscheidung des GC, sie zu entsorgen, überprüft?
Der Grund, den ich frage, ist, dass ich zuvor einige statische Klassen in C # geschrieben habe und das Verhalten anders ist, als ich erwartet hätte. Ich hätte erwartet, dass statische Klassen für jede Anforderung eindeutig sind, aber das scheint nicht der Fall zu sein.
Wenn sie nicht für jede Anfrage eindeutig sind, gibt es eine Möglichkeit, dies zuzulassen?
UPDATE:
Die Antwort, die driis mir gab, war genau das, was ich brauchte. Ich habe bereits eine Singleton-Klasse verwendet, jedoch eine statische Instanz, und wurde daher von Anforderungen gemeinsam genutzt, auch wenn die Benutzer unterschiedlich waren, was in diesem Fall eine schlechte Sache war. Die Verwendung HttpContext.Current.Items
löst mein Problem perfekt. Für alle, die in Zukunft auf diese Frage stoßen, ist hier meine Implementierung, vereinfacht und verkürzt, damit das Muster leicht zu verstehen ist:
using System.Collections;
using System.Web;
public class GloballyAccessibleClass
{
private GloballyAccessibleClass() { }
public static GloballyAccessibleClass Instance
{
get
{
IDictionary items = HttpContext.Current.Items;
if(!items.Contains("TheInstance"))
{
items["TheInstance"] = new GloballyAccessibleClass();
}
return items["TheInstance"] as GloballyAccessibleClass;
}
}
}
filterContext.Result = new RedirectResult(...)
Hinweis : Wenn Sie Ihre Anfrage beispielsweise umleiten, verlieren Sie Ihre Artikel, weil ein neuer HttpContext erstellt wird. Weitere Details hier: stackoverflow.com/questions/16697601/…Antworten:
Ihre statischen Klassen und statischen Instanzfelder werden von allen Anforderungen an die Anwendung gemeinsam genutzt und haben dieselbe Lebensdauer wie die Anwendungsdomäne. Daher sollten Sie bei der Verwendung statischer Instanzen vorsichtig sein, da möglicherweise Synchronisierungsprobleme und dergleichen auftreten. Beachten Sie auch, dass statische Instanzen nicht GC-geprüft werden, bevor der Anwendungspool recycelt wird, und daher alles, worauf die statische Instanz verweist, nicht GC-geprüft wird. Dies kann zu Problemen bei der Speichernutzung führen.
Wenn Sie eine Instanz mit der gleichen Lebensdauer wie eine Anfrage benötigen, würde ich empfehlen, die
HttpContext.Current.Items
Sammlung zu verwenden. Dies ist beabsichtigt, um Dinge zu speichern, die Sie während der Anfrage benötigen. Für ein besseres Design und eine bessere Lesbarkeit können Sie das Singleton-Muster verwenden, um diese Elemente zu verwalten. Erstellen Sie einfach eine Singleton-Klasse, in der die Instanz gespeichert istHttpContext.Current.Items
. (In meiner allgemeinen Bibliothek für ASP.NET habe ich zu diesem Zweck eine generische SingletonRequest-Klasse).quelle
HttpContext.Current.Items
?"static instances will not be GC'ed before the application pool is recycled, and therefore everything that is referenced by the static instance, will not be GC'ed"
- Gibt es eine Quelle dafür, weil es keinen Sinn ergibt und im Widerspruch zu dem steht, was ich an anderer Stelle gelesen habe. Wenn der AppPool recycelt wird, wird die zugehörige App-Domäne vollständig abgerissen und GC-fähig. In diesem Fall werden alle zugehörigen statischen Instanzen ebenfalls einer GC unterzogen, da ihr Stammverzeichnis (die AppDomain) nicht mehr vorhanden ist. Im Rahmen des Pool-Recyclings wird eine neue AppDomain erstellt und die zugehörigen statischen Instanzen initialisiert.Statische Mitglieder haben nur einen Bereich des aktuellen Arbeitsprozesses, daher hat dies nichts mit Anforderungen zu tun, da unterschiedliche Anforderungen möglicherweise von demselben Arbeitsprozess verarbeitet werden oder nicht.
Übrigens ist die Standardanzahl der Arbeitsprozesse 1, weshalb das Web voll von Leuten ist, die denken, dass statische Mitglieder einen Bereich der gesamten Anwendung haben.
quelle
Da die Typen in einer App-Domäne enthalten sind, würde ich erwarten, dass statische Klassen vorhanden sind, solange die App-Domäne nicht recycelt wird oder wenn die Anforderung von einer anderen App-Domäne bedient wird.
Ich kann mir verschiedene Möglichkeiten vorstellen, um Objekte für eine bestimmte Anforderung spezifisch zu machen. Dies hängt davon ab, was Sie tun möchten. Beispielsweise können Sie das Objekt in Application.BeginRequest instanziieren und dann im HttpRequest-Objekt speichern, damit alle Objekte in darauf zugreifen können die Anforderungsverarbeitungspipeline.
quelle
Nee. Statische Mitglieder gehören dem ASP.NET-Prozess und werden von allen Benutzern der Web-App gemeinsam genutzt. Sie müssen sich anderen Sitzungsverwaltungstechniken wie Sitzungsvariablen zuwenden.
quelle
Normalerweise sind statische Methoden, Eigenschaften und Klassen bei der
Application
Ebene üblich. Solange die Anwendung gültig ist, werden sie gemeinsam genutzt.Sie können ein anderes Verhalten angeben, indem Sie das
ThreadStatic
Attribut verwenden. In diesem Fall sind sie spezifisch für den aktuellen Thread, der meiner Meinung nach für jede Anfrage spezifisch ist.Ich würde dies jedoch nicht empfehlen, da es zu kompliziert erscheint.
Sie können verwenden
HttpContext.Current.Items
, um Dinge für eine Anfrage einzurichten, oderHttpContext.Current.Session
einzurichten um Dinge für einen Benutzer einzurichten (über Anfragen hinweg).Im Allgemeinen ist es jedoch
Server.Transfer
am besten, Dinge einmal zu erstellen und sie dann explizit per Methodenaufruf zu übergeben , es sei denn, Sie müssen Dinge wie verwenden .quelle