Voici les spécifications:Web Service Appel en JavaScript Causer écran blanc de la mort (WSOD) dans le navigateur
- ASP.NET 3.5 en utilisant ASP.NET AJAX AJAX Control Toolkit
- jQuery 1.3.2
- services web
- IIS6 sur Windows Server 2003 SP1
- SP1 SQLServer 2005 site SP3 est SSL
- Infragistics Web Components 2009 Vol. 2 (en utilisant des contrôles non-Aïkido), UltraWebGrid et Tree control sont les principaux utilisés.
Voici le problème: Je reçois l'écran blanc de la mort (WSOD) dans IE 7/8. Fondamentalement, j'ai une page qui a un volet gauche qui a un contrôle AJAXControl Toolkit Accordion où chaque contenu des volets accordéon est un contrôle d'arbre Infragistics. Le volet droit est un <div>
qui a un dont le contenu est rechargé en fonction de ce qui a été cliqué dans le volet de menu de gauche.
Dans le , une page contenant un ou plusieurs contrôles UltraWebGrid est chargée lorsque vous cliquez sur un élément de menu dans le volet de gauche. Les grilles ont toutes une colonne de bouton modèle. Lorsque vous cliquez sur le bouton Modifier d'une ligne de la grille une fenêtre contextuelle pour modifier l'enregistrement est ouverte. Cela fonctionne bien pour une dizaine de fois, puis la dixième fois (parfois plus tôt), la fenêtre contextuelle s'ouvre avec l'URL correcte dans la barre d'adresse, mais la page ne se charge jamais.
Nous avons une application qui utilise une fenêtre contextuelle pour la mise à jour des enregistrements. La plupart du temps, lorsque vous cliquez sur le bouton [Modifier] pour modifier un enregistrement, la fenêtre contextuelle s'ouvre et charge la page de mise à jour. Cependant, après avoir modifié les enregistrements pendant un certain temps, tout à coup la fenêtre contextuelle s'ouvre, mais elle reste vide et se bloque. L'URL est dans la barre d'adresse.
Chargement de Fiddler J'ai remarqué que la demande de la page de mise à jour n'est jamais envoyée, ce qui me porte à croire que c'est une sorte de blocage du côté client. Si je copie la même URL que dans la fenêtre contextuelle dans une nouvelle fenêtre de navigateur, la page se charge généralement bien.
Observations: - Puisque la requête n'est jamais envoyée au serveur, elle est définitivement liée au client ou au navigateur. - Apparaît seulement quand il y a un semblant de trafic sur le site qui est bizarre parce que cela semble être contenu dans le code côté client - Un service Web est appelé en arrière-plan toutes les quelques secondes pour vérifier si l'utilisateur est connecté, mais cela ne provoque pas le gel.
Je suis vraiment perdue ici. J'ai googlé sur WSOD mais peu de choses semblent liées à mon WSOD spécifique. Des idées?
Qu'est-ce que le problème est vraiment
tourne donc les fuites de mémoire (bien que j'ai scellé un peu sur le côté client) ne sont pas la question. Le problème concerne les appels de service Web effectués du côté client. Il y en a un qui vérifie si un utilisateur est connecté toutes les 4 secondes (pour synchroniser avec une autre fenêtre) et puis il y a des appels de service Web pour obtenir les préférences de l'utilisateur pour une fenêtre contextuelle et un état de grille. D'après ce que j'ai lu, les services Web doivent être asynchrones. J'ai supposé en les appelant de JavaScript avec des rappels de succès/échec qu'ils étaient asynchrones mais ils ne sont pas vraiment.Ils sont asynchrones du point de vue client/navigateur, mais du côté serveur, l'appel au service web est effectué et retourne quand il est terminé en retardant toutes les autres opérations puisqu'il y a un nombre limité de connexions.
Alors, quel est le moyen le plus simple de rendre les méthodes de service Web asynchrones? Le service Web doit-il être converti en un service Web WCF ou puis-je utiliser mon appel de service Web ASP.NET existant?
Et pour des raisons historiques, voici ce que je pensais que le problème était à l'origine:
Je n'ai pas pu reproduire ce localement ou sur nos serveurs de test. Cependant, j'ai obtenu Fiddler pour simuler des vitesses de modem et tout à coup je peux répliquer le WSOD sur mon PC local. Il semble donc que la connexion soit lente ou temporairement lente lors de l'ouverture d'une fenêtre contextuelle qui l'étouffe, du moins dans mon environnement de test.
J'ai fait un autre test en cours d'exécution IE sans add-ons, iexplore.exe -extoff
, mais se retrouvent avec le même résultat. J'ai également corrigé un problème où le iframe de la page était recréé à chaque fois que l'URL de l'iframe était modifiée. Une partie de ma logique a été omise. Maintenant, l'iframe est seulement créé une fois. Après cela, seul l'attribut src
est mis à jour lorsque je veux charger un nouveau contenu ... mon goof. J'ai remarqué quelques références de fenêtres persistantes dans les fermetures de JavaScript, alors maintenant celles-ci sont explicitement définies sur null dans les fermetures quand j'en ai fini avec elles.
J'ai aussi fait une enquête sur la fuite de mémoire: - Pour autant que je peux dire que je n'ai pas de références circulaires dans les DOM et JavaScript ou les autres motifs de fuite mentionnés ici, http://www.ibm.com/developerworks/web/library/wa-memleak/?S_TACT=105AGX52&S_CMP=cn-a-wa
J'ai ajouté le code de purge du Crockenator pour les fuites de mémoire IE (voir http://www.crockford.com/javascript/memory/leak.html):
$ (document) .ready (function() { purge de la fonction (d) { var a = d.attributes, i, l , n;
if (a) { l = a.length; for (i = 0; i < l; i += 1) { if (a[i]) { n = a[i].name; if (typeof d[n] === 'function') { d[n] = null; purgeCount++; } } } } a = d.childNodes; if (a) { l = a.length; for (i = 0; i < l; i += 1) { purge(d.childNodes[i]); } } } $(window).unload(function() { purge(document.body); //alert("purge count: " + purgeCount); });
});
Aucune de mes améliorations n'a corrigé le problème. dans mon scénario de test local. Des idées? N'importe qui? N'importe qui? Bueller?
Dernière mise à jour
Merci David pour avoir souligné qu'il était l'état de session causant des problèmes dans les services Web. "ASP.NET met en file d'attente toutes les requêtes vers la même 'session', donc si la première requête bloque trop longtemps, elle bloquera toutes les autres requêtes en file d'attente."
Alors, que nous avons fini par faire était d'essayer de minimiser les services Web en utilisant l'état de session, mais nous avons également ajouté les paramètres recommandés par Microsoft pour le nombre de connexions, voir http://msdn.microsoft.com/en-us/library/ff647786.aspx#scalenetchapt10_topic9
Les méthodes de service Web qui provoquent l'émission e utilise l'état de session, c'est-à-dire [WebMethod (EnableSession = true)]. Existe-t-il un meilleur moyen d'accéder à la session dans un service que via [WebMethod (EnableSession = true)]? Les services Web que je cours doivent être conscients de la session d'un utilisateur et être appelé à partir de JavaScript. – nickytonline
Malheureusement, ASP.NET impose la synchronisation des requêtes pour les sessions, vous devez implémenter une autre forme de stockage d'état inter-requête et rendre vos méthodes Web désactivées. La synchronisation des requêtes pour l'état de la session est la raison pour laquelle vous n'avez pas à "verrouiller" pour obtenir/définir à partir de la session. Si vous déplacez votre stockage vers un hachage spécifique à l'utilisateur dans Application [], vous ne recevrez pas la synchronisation des requêtes, mais vous aurez besoin de Application.Lock() et Application.Unlock() pour accéder à ces données. – David
Avez-vous besoin d'un accès en écriture à l'état de la session? Si vous les changez en lecture seule, ils ne se bloqueront pas, mais ils seront toujours bloqués par toute autre page qui obtient un verrou en écriture sur la session. Voir la dernière section de: http://msdn.microsoft.com/en-us/library/ms178581.aspx – David