Question

J'essaie d'envoyer du contenu au client avant de faire un long travail:

Response.Write("Processing...");
Response.Flush();
System.Threading.Thread.Sleep(5000);
Response.Write("Finish");
Response.End();

Dans Firefox, cela fonctionne comme prévu, mais dans IE8, Safari et Chrome, il attend que tout le code soit traité, puis affiche tout le texte.

J'ai essayé d'envoyer un code HTML mieux formé, comme dans l'exemple ci-dessous, mais les résultats sont identiques:

Response.Write("<html><head><title>test</title></head><body>Processing...</body></html>");
Response.Flush();
System.Threading.Thread.Sleep(5000);
Response.Write("Finish");
Response.End();

Merci!

Était-ce utile?

La solution

Le problème que vous rencontrez est que la réponse que vous envoyez est toujours incomplète. Même si vous effacez le contenu des tampons dans le navigateur, il appartient au navigateur d'attendre la fin de la réponse ou de traiter ce qu'il a jusqu'à présent - d'où la différence entre les navigateurs.

Ce qui est encore pire, c'est que vous pouvez vous attendre au même comportement de la part de certains nœuds intermédiaires concentrateurs, pare-feu, etc. situés sur Internet entre votre serveur et le navigateur.

En bout de ligne, si vous voulez vous assurer que le navigateur utilise quelque chose dans votre flux de données, vous devez le compléter avec Response.End.

En d’autres termes, si vous souhaitez envoyer d’abord certaines de vos données de réponse et retarder l’envoi du reste, votre meilleure option est de fractionner la réponse en deux, complétez la première et téléchargez la deuxième partie séparément

Autres conseils

Un moyen facile de résoudre ce problème consiste à placer un " Veuillez patienter, traitement " page devant la page qui fait le travail. Veuillez attendre & Quot; Un message s'affiche et le traitement commence immédiatement en utilisant une balise meta refresh et / ou javascript pour rediriger le contenu vers la page de traitement actuelle.

& "Veuillez patienter s'il vous plaît &" Page:

<html>
<head>
  <meta http-equiv="refresh" content="0;url=process.aspx?option1=value&...." />
  <title>Please Wait, Processing</title>
</head>
<body>
  Processing...
</body>
<script type="text/javascript">
  window.location = "process.aspx?option1=value&....";
</script>
</html>

Notes:

  1. Deux méthodes sont utilisées pour lancer le traitement afin de s'assurer que si un navigateur ne peut en utiliser aucune, il utilisera, espérons-le, l'autre méthode.
  2. Vous devrez remplacer l'URL de traitement et la chaîne de requête en conséquence.
  3. Un inconvénient de cette méthode est que si l'utilisateur clique sur le bouton retour du navigateur, il reviendra à la " veuillez patienter " page du " processus " page, ce qui signifie qu'il va accidentellement lancer le travail à nouveau. Je vais laisser ce défi pour un autre sujet!

Sachez également que si votre serveur IIS compresse la sortie avec GZIP, il semblera alors ignorer tous les Response.Flush appels.

Ceci est activé par défaut dans IIS7 et sous Windows 7.

Et si vous testez avec Fiddler, assurez-vous d'activer & "Streaming &"; mode, ou Fiddler collectera le code HTML vidé et le conservera jusqu'à ce que la connexion soit établie.

Lorsque vous appelez Response.Flush () avant la fin de la réponse (avant que Content-Length soit connu), le runtime ASP.NET génère une réponse partielle à l'encodage en bloc. C'est au navigateur de décider comment rendre cela. Lors de mes tests, j'ai constaté que les navigateurs ont tendance à rendre les images (<img> balises) incluses dans une réponse partielle. Vous pouvez essayer.

Cependant, faites attention de ne pas envoyer </html> trop tôt; les navigateurs peuvent ignorer quoi que ce soit au-delà de ce point. Les navigateurs rendent toujours les pages partielles en partie. Vous pouvez donc commencer par le début de votre page comme d'habitude.

Au cas où cela serait utile, j’expliquerai en détail un exemple de ceci dans mon livre, y compris une trace de paquet qui montre exactement ce qui se passe sur le réseau: ASP.NET ultra-rapide .

Je pense que les navigateurs obtiennent et utilisent le contenu en fonction de sa longueur. Vous pouvez donc essayer de remplir environ 1000 caractères. Par exemple:

string myVeryShortMessage = & "Traitement en cours ... &" ;;;

Response.Write (myVeryShortMessage.PadRight (1000)); Response.Flush ();

System.Threading.Thread.Sleep (5000);

Response.Write (" Terminer ". .PadRight (1000)); Response.Flush ();

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