2009-11-14 4 views
15

Je ne peux pas faire plus d'une requête à la fois dans asp.net tant que la session est active. Pourquoi cette limitation existe-t-elle? Y a-t-il un moyen de contourner ce problème?Un seul utilisateur asp.net peut-il faire plusieurs requêtes à la fois si la session est en cours d'utilisation?

Ce problème peut être démontré avec une application WebForms avec seulement 3 pages aspx simples (bien que la limitation s'applique toujours dans asp.net mvc).

Créez une application Web asp.net 3.5.

Il devrait y avoir seulement trois pages: NoWait.aspx, Wait.aspx et SessionStart.aspx

NoWait.aspx a cette pépite unique ajoutée entre les balises div par défaut: <% = DateTime.Now.Ticks %>. Le code-behind pour cette page est la valeur par défaut (vide). Wait.aspx ressemble à NoWait.aspx, mais une ligne a été ajoutée à Page_Load dans le code-behind: Thread.Sleep (3000); // attendre 3 secondes

SessionStart.aspx ressemble également à NoWait.aspx, mais il a cette seule ligne dans son code-behind: Session ["Whatever"] = "Anything";

Ouvrez un navigateur et accédez à NoWait.aspx. Il montre correctement un nombre dans la réponse, comme: "633937963004391610". Continuez à rafraîchir et il ne cesse de changer le nombre. Super jusqu'à présent! Créez un nouvel onglet dans le même navigateur et accédez à Wait.aspx. Il reste pendant 3 secondes, puis écrit le nombre à la réponse. Super jusqu'à présent! Non, essayez ceci: Allez à Wait.aspx et pendant qu'il tourne, passez rapidement à NoWait.aspx et rafraîchissez-vous. Même lorsque Wait.aspx est en veille, NoWait.aspx fournira une réponse. Super jusqu'à présent. Vous pouvez continuer à actualiser NoWait.aspx pendant que Wait.aspx tourne, et le serveur envoie une réponse à chaque fois. C'est le comportement auquel je m'attends.

Maintenant c'est là que ça devient bizarre.

Dans un troisième onglet, dans le même navigateur, visitez SessionStart.aspx. Ensuite, placez le curseur sur Wait.aspx et actualisez. Pendant la rotation, placez le curseur sur NoWait.aspx et actualisez. NoWait.aspx n'enverra pas de réponse tant que Wait.aspx n'aura pas été exécuté! Cela prouve que lorsqu'une session est active, vous ne pouvez pas faire de requêtes simultanées avec le même utilisateur. Les demandes sont toutes mises en file d'attente et servies de manière synchrone. Je ne m'attends pas ou je ne comprends pas ce comportement. J'ai testé cela sur le serveur Web intégré de Visual Studio 2008, ainsi que sur IIS 7 et IIS 7.5.

J'ai donc quelques questions:

1) Ai-je raison qu'il ya effectivement une limitation ici, ou est mon test ci-dessus invalide parce que je fais quelque chose de mal?

2) Existe-t-il un moyen de contourner cette limitation? Dans mon application Web, certaines choses mettent du temps à s'exécuter et j'aimerais que les utilisateurs puissent faire des choses dans d'autres onglets pendant qu'ils attendent une grosse requête à remplir. Puis-je en quelque sorte configurer la session pour permettre des "lectures sales"? Cela pourrait l'empêcher d'être verrouillé pendant la demande?

3) Pourquoi cette limitation existe-t-elle? Je voudrais bien comprendre pourquoi cette limitation est nécessaire. Je pense que je serais un meilleur développeur si je le savais!

Répondre

11

Here is a link talking about session state and locking. Il effectue un verrouillage exclusif.

La méthode la plus simple consiste à rendre les tâches longues asynchrones.Vous pouvez exécuter les tâches longues sur un fil séparé ou utiliser et asynchronous delegate et renvoyer une réponse au navigateur immédiatement. La page côté client peut envoyer des requêtes au serveur pour vérifier et voir si cela est fait (par ajax le plus probable), et quand le serveur dit au client qu'il est fini, avertir l'utilisateur. De cette façon, bien que les requêtes du serveur doivent être traitées une à la fois par le serveur, cela ne ressemble pas à l'utilisateur. Cela a son propre ensemble de problèmes, et vous devrez vous assurer que compte pour la fermeture du contexte HTTP car cela disposera de certaines fonctionnalités dans la session asp.net. Un exemple dont vous devrez probablement tenir compte est probablement de libérer un verrou sur la session, si cela se produit réellement.

Ce n'est pas trop surprenant que cela pourrait être une limitation. Chaque navigateur aurait sa propre session, avant l'avènement d'ajax, les requêtes post-retour étaient synchrones. Rendre la même session gérer concurrente pourrait devenir vraiment moche, et je peux voir comment cela ne serait pas une priorité pour les équipes IIS et ASP.NET à ajouter.

+0

Et nous l'avons. J'ai vérifié cette page plus tôt aujourd'hui mais je n'ai pas tout lu. Le problème de la concurrence est le tout dernier paragraphe! Merci pour le lien! – Chris

9

Pour des raisons que Kevin décrit, les utilisateurs ne peuvent pas accéder à deux Les pages qui pourraient écrire dans leur état de session en même temps - le cadre lui-même ne peut pas exercer de contrôle précis sur le verrouillage du magasin de session, il doit donc le verrouiller pour des requêtes entières. Pour contourner ce problème, les pages read peuvent indiquer que cela se produit. ASP.NET n'obtiendra pas un verrou d'écriture d'état de session pour eux:

// Or false if it doesn't need access to session state at all 
EnableSessionState="ReadOnly" 
Questions connexes