web-dev-qa-db-fra.com

Durée de vie de la variable statique ASP.NET

Je tiens certaines informations dans des variables statiques définies dans la classe de page (pas dans Global.asax). Je ne déclare que la variable dans le code comme:

protected static int SomeGlobalUnsecureID;
protected static string SomeGlobalUnsecureString;

et définissez la variable dans l'événement PageLoad. Par exemple, je vérifie l'ID de la base de données; s'il est différent de SomeGlobalUnsecureID, je mets à jour SomeGlobalUnsecureID et String ailleurs, sinon je les laisse tels quels. Ceci est parfaitement sécurisé dans mon application. logique (c’est-à-dire que ces données ne sont pas sécurisées, tout le monde peut y accéder, pas de problème); la seule chose que je veux accomplir est

  1. Détenir la même quantité de mémoire indépendamment des utilisateurs connectés

  2. Modifiez si et seulement si les informations persistantes diffèrent de celles de "mémoire" (car lire la chaîne prend beaucoup de temps.

Maintenant, depuis que je vérifie PageLoad, les pages rechargées ne me posent aucun problème. Cependant, ma page est pleine de méthodes Web et parfois je vois que les variables statiques sont mises à zéro. Et la partie étrange est; la session est toujours active même lorsque les variables statiques sont mises à zéro (so-> pas de serveur ou de pool d'applications redémarrent, etc.)

C'est vraiment étrange pour moi. Je suppose que la variable statique conservera sa valeur jusqu'à la fin (en quelque sorte) de l'application. Mais même la session n'a pas expiré, la variable statique est mise à zéro. Que suggérez-vous? L'utilisation de variables d'application est-elle un meilleur choix? Tous les documents que j'ai lus sur le Web suggèrent des variables statiques plutôt que des variables d'application. Dois-je les déclarer d'une manière ou d'une autre?

71
paul simmons

Les variables statiques persistent pendant toute la vie du domaine d'application. Ainsi, les deux choses qui provoqueront la "réinitialisation" de vos variables statiques sont le redémarrage d'un domaine d'application ou l'utilisation d'une nouvelle classe. Dans votre cas avec des variables statiques stockées dans une classe de pages aspx, vous risquez de perdre ces variables lorsque ASP.NET décide de recompiler la page aspx en une nouvelle classe, en remplaçant l'ancienne classe par la nouvelle.

Pour ces raisons, si le système décide de redémarrer ou de remplacer la classe ( . NET ne tue ni ne décharge les classes/assemblys dans un domaine d'application en cours d'exécution ), vos variables statiques seront réinitialisées car vous obtiendrez une nouvelle classe avec le redémarrage ou le remplacement. Ceci s’applique à la fois aux pages aspx et à classes du dossier App_Code

ASP.NET remplacera une classe si, pour une raison quelconque, pense qu'il est nécessaire de la recompiler ( voir Compilation dynamique ASP.NET ).

Vous ne pouvez pas empêcher la perte de variables statiques du redémarrage d'un domaine d'application, mais vous pouvez essayer d'éviter le remplacement de classe. Vous pouvez placer vos variables statiques dans une classe qui n'est pas une page aspx ni dans le répertoire App_Code. Vous voudrez peut-être les placer sur un static class quelque part dans votre programme.

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

Les variables statiques sont par pool, cela signifie que si vous avez 2 pools qui exécutent votre site asp.net, vous avez 2 variables statiques différentes. ( mode jardin Web )

Les variables statiques sont perdues si le système redémarre votre application asp.net avec l’un de ces moyens.

  1. le pool décide qu'il faut faire une recompilation.
  2. Vous ouvrez le fichier app_offline.htm
  3. Vous faites un redémarrage manuel du pool
  4. Le pool atteint certaines limites que vous avez définies et les fait redémarrer.
  5. Pour une raison quelconque, vous redémarrez l'iis ou le pool.

Ces variables statiques ne sont pas thread-safe et vous devez utiliser le mot clé lock si vous y accédez à partir de threads différents.

Dans la mesure où un redémarrage de l'application réinitialisera vos statistiques, quoi qu'il en soit, si vous souhaitez réellement conserver vos données, vous devez les stocker dans une base de données à l'aide de classes personnalisées. Vous pouvez stocker des informations par utilisateur dans État de la session avec un mode d'état de session de la base de données . Les variables/l'état d'application ASP.NET ne vous aideront pas car elles sont stockées en mémoire, pas dans la base de données , elles sont donc également perdues au redémarrage du domaine d'application.

93
Aristos

Je pense que les deux points suivants sont également importants pour la durée de vie des variables statiques:

1 - Dans les paramètres avancés de votre pool d'applications, cochez le paramètre "Recyclage" -> "Intervalle de temps normal (minutes)". Sa valeur par défaut est 1740, ce qui signifie que toutes les 29 heures, vos variables statiques sont perdues à cause du recyclage de votre pool d'applications. Ce paramètre est utilisé pour mettre fin aux fuites de mémoire possibles. Je ne changerais pas ce réglage ..

2 - Dans les paramètres avancés de votre pool d'applications, cochez le paramètre "Modèle de processus" -> "Délai d'inactivité (minutes)". Sa valeur par défaut est 20, ce qui signifie que toutes les 20 minutes d'inactivité dans votre pool d'applications, les processus de travail sont arrêtés/suspendus, ce qui entraînera la perte de vos variables statiques. Ce paramètre est utilisé pour libérer des ressources lorsque le pool d'applications n'est pas utilisé pendant un certain temps. Vous pouvez le définir sur 0 pour désactiver le délai.

15
sotn