Sur un site Web ASP.NET, les classes statiques sont-elles uniques à chaque requête Web, ou sont-elles instanciées chaque fois que nécessaire et GC chaque fois que le GC décide de les éliminer?
La raison pour laquelle je pose la question est que j'ai déjà écrit des classes statiques en C # et que le comportement est différent de ce à quoi je m'attendais. Je me serais attendu à ce que les classes statiques soient uniques à chaque requête, mais il ne semble pas que ce soit le cas.
S'ils ne sont pas uniques à chaque demande, y a-t-il un moyen de les autoriser?
MISE À JOUR:
La réponse que driis m'a donnée était exactement ce dont j'avais besoin. J'utilisais déjà une classe singleton, mais elle utilisait une instance statique et était donc partagée entre les demandes même si les utilisateurs étaient différents, ce qui dans ce cas était une mauvaise chose. L'utilisation HttpContext.Current.Items
résout parfaitement mon problème. Pour tous ceux qui tombent sur cette question à l'avenir, voici mon implémentation, simplifiée et raccourcie pour qu'il soit facile de comprendre le modèle:
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(...)
vous perdrez vos éléments car un nouveau HttpContext sera créé. Plus de détails ici: stackoverflow.com/questions/16697601/…Réponses:
Vos classes statiques et vos champs d'instance statiques sont partagés entre toutes les demandes adressées à l'application et ont la même durée de vie que le domaine d'application. Par conséquent, vous devez être prudent lorsque vous utilisez des instances statiques, car vous pourriez avoir des problèmes de synchronisation, etc. Gardez également à l'esprit que les instances statiques ne seront pas GC avant que le pool d'applications ne soit recyclé, et par conséquent, tout ce qui est référencé par l'instance statique ne sera pas GC. Cela peut entraîner des problèmes d'utilisation de la mémoire.
Si vous avez besoin d'une instance avec la même durée de vie qu'une requête, je vous suggère d'utiliser la
HttpContext.Current.Items
collection. C'est par conception censé être un endroit pour stocker les choses dont vous avez besoin tout au long de la demande. Pour une meilleure conception et une meilleure lisibilité, vous pouvez utiliser le modèle Singleton pour vous aider à gérer ces éléments. Créez simplement une classe Singleton qui stocke son instance dansHttpContext.Current.Items
. (Dans ma bibliothèque commune pour ASP.NET, j'ai une classe SingletonRequest générique à cet effet).la source
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"
- Y a-t-il une source pour cela, car cela n'a aucun sens et entre en conflit avec ce que j'ai lu ailleurs. Lorsque l'AppPool est recyclé, le domaine d'application associé est complètement démoli et GC. Lorsque cela se produit, toutes les instances statiques associées seront également GC car leur racine (AppDomain) a disparu. Dans le cadre du recyclage du pool, un nouvel AppDomain est créé et ses instances statiques associées sont initialisées.Les membres statiques ont une étendue du processus de travail actuel uniquement, donc cela n'a rien à voir avec les demandes, car différentes demandes peuvent ou non être traitées par le même processus de travail.
À propos, le nombre par défaut de processus de travail est de 1, c'est pourquoi le Web regorge de gens qui pensent que les membres statiques ont une portée de l'application entière.
la source
Étant donné que les types sont contenus dans un domaine d'application, je m'attendrais à ce que des classes statiques soient présentes tant que le domaine d'application n'est pas recyclé ou si la demande est servie par un domaine d'application différent.
Je peux penser à plusieurs façons de rendre des objets spécifiques à une demande particulière en fonction de ce que vous voulez faire, par exemple, vous pouvez instancier l'objet dans Application.BeginRequest, puis le stocker dans l'objet HttpRequest afin qu'il soit accessible par tous les objets de le pipeline de traitement des demandes.
la source
Nan. Les membres statiques appartiennent au processus ASP.NET et sont partagés par tous les utilisateurs de l'application Web. Vous devrez vous tourner vers d'autres techniques de gestion de session telles que les variables de session.
la source
Normalement, les méthodes, propriétés et classes statiques sont courantes au
Application
niveau. Tant que l'application existe, elles sont partagées.Vous pouvez spécifier un comportement différent à l'aide de l'
ThreadStatic
attribut. Dans ce cas, ils seront spécifiques au fil actuel, qui, je pense, est spécifique à chaque demande.Je ne conseillerais pas cela car cela semble trop compliqué.
Vous pouvez utiliser
HttpContext.Current.Items
pour configurer des éléments pour une demande ouHttpContext.Current.Session
pour configurer des éléments pour un utilisateur (sur plusieurs demandes).En général cependant, à moins que vous n'ayez à utiliser des choses comme
Server.Transfer
, le meilleur moyen consiste essentiellement à créer des choses une fois, puis à les passer explicitement via l'invocation de méthode.la source