Question

J'ai une application web qui utilise actuellement le HttpContext actuel pour stocker un contexte de données LINQ. Le contexte est conservé pour la demande en cours, sur une base par utilisateur, par Rick Strahl Blog :

string ocKey = "ocm_" + HttpContext.Current.GetHashCode().ToString("x")  
Thread.CurrentContext.ContextID.ToString();

if (!HttpContext.Current.Items.Contains(ocKey))
{
    // Get new Data Context and store it in the HTTP Context
}

Cependant, j'ai quelques scripts qui exécutent à partir du fichier global.asax, que ne pas un HttpContext. Le HttpContext.Current est NULL , car le serveur est celui qui fait la "demande".

Y at-il un objet équivalent que je peux utiliser pour stocker le contexte des données? Je n'ai donc pas à vous soucier de recréer, et attacher / détacher des objets? Je veux seulement persister le contexte de la durée de vie de mes processus.

MISE À JOUR:

Je suis en train d'essayer d'utiliser une variable statique dans ma classe d'aide DAL. sur le premier appel à l'une des méthodes de la classe DataContext est instancié, et stockée dans la variable statique. A la fin de mon processus, j'appelle une autre méthode qui appelle Dispose sur le DataContext, et définit la variable statique NULL.

Était-ce utile?

La solution

Pouvez-vous pas simplement utiliser une variable statique spécifiquement pour les scripts? Cela aura le même temps de la vie comme AppDomain. Vous devriez probablement penser soigneusement au sujet des préoccupations de concurrence, mais il semble que la façon la plus simple de garder une valeur autour.

(je viens de vérifier, et bien une instance de HttpApplication peut être utilisé pour traiter plusieurs demandes, chacun sert qu'une seule demande à la fois -. Ce qui suggère que plusieurs instances sont créées pour le traitement des requêtes simultanées Je n'ai pas validé, mais il ne semble que ce ne serait pas sûr de le garder dans une variable d'instance.)

EDIT: La réponse de Josh suggère que vous voulez que ce soit par thread. Cela me semble un peu étrange, comme à moins que vous avez un beaucoup de ces événements qui se produisent, vous êtes tout à fait susceptible de ne les voient jamais exécuter sur différents threads, ce qui rend toute entreprise de partage inutile. Si vous ne voulez vraiment ce genre de chose, je vous suggère simplement en utilisant une variable d'instance dans la classe dérivée HttpApplication-- pour exactement la raison décrite dans le paragraphe ci-dessus:)

Autres conseils

Pourquoi ne pas utiliser la HttpContext actuelle? Les scripts dans votre fichier global.asax sont le résultat d'une demande entrant dans le serveur, donc il devrait y avoir un contexte associé à cette demande que vous pouvez saisir.

Je ne comprends pas la nécessité de générer la clé sur la base du hashcode ou le fil. Il va y avoir une instance distincte de HttpContext pour chaque requête qui est fournie, et cette instance va être spécifique au thread qui traite la demande. À cause de cela, la clé est à peu près sans valeur quand il est basé sur l'instance de HttpContext et le fil.

En outre, comment vous disposez de DataContext lorsque vous avez terminé? Il implémente IDisposable pour une raison, donc je recommande contre une instance partagée comme celui-ci.


UPDATE

Dans les commentaires, il indique qu'il ya une minuterie qui est en cours d'exécution qui exécute les scripts. Au lieu de la minuterie, je recommande la mise en place d'une tâche planifiée qui fera appel à un webservice ou d'une page prédéterminée sur le site qui effectuera la tâche. Ensuite, vous aurez toujours un HttpContext de travailler avec.

HttpContext.Current est une méthode statique et devrait être disponible à partir de n'importe où tant que le code est exécuté dans le cadre d'une demande.

Dans votre cas, vous n'êtes pas exécuter dans le cadre d'une demande, vous pouvez envisager d'utiliser Application.Cache mais je voudrais mettre en garde contre la tenue d'une DataContext ouverte. Je ne suis pas très famillar avec LINQ to Entities, donc je peux me tromper, mais la mise en cache généralement les éléments liés à la base de données telles que les connexions sont mauvaises.

Je recommande également que vous envisagez de déplacer la logique de votre global.asax et à un service de fenêtres. Cela vous laissera plus de contrôle sur ces tâches, par exemple, vous pouvez les fermer seperatley du site Web.

Modifier

Comme JS indique que vous pouvez utiliser une variable statique. Vous pouvez également définir une variable d'instance marquée avec l'attribut ThreadLocal. Cela donnera chaque fil sa propre copie de la variable, et peut éliminer contention. Puisque vous voulez que chaque fil d'avoir sa propre copie de toute façon.

Y at-il une raison pour laquelle ceux-ci doivent être traitées de la même façon que les autres DataContexts? Il me semble que si le contexte est nécessaire que l'intérieur de la routine de la gestion des événements, vous ne devriez pas avoir besoin de le garder autour. Surtout si elle est en Application_Start (selon votre commentaire), je ne pris la peine de mettre en cache nulle part -. Il suffit d'utiliser localement et de le transmettre aux autres méthodes, au besoin

Régler le DataContext comme paramètre d'état lors de la création de la minuterie. D'après les informations que vous avez publié sur les commentaires, il me semble que votre DataContext est plus liée aux minuteries que toute autre chose.

Évitez également d'utiliser le même DataContext pour différents temporisateurs, parce que vous finiriez avec des modifications mixtes des différents compteurs. De plus, assurez-vous que votre même logique de minuterie est exécuté pas deux fois, car il causerait la même période trop courte dire sans contrôle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top