Pregunta

Estoy intentando enviar algo de contenido al cliente antes de hacer un trabajo largo:

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

En Firefox funciona como se esperaba, pero en IE8, Safari y Chrome espera hasta que se procese todo el código y luego muestra todo el texto.

He intentado enviar un HTML mejor formado como el siguiente ejemplo, pero obtengo los mismos resultados:

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

¡Gracias!

¿Fue útil?

Solución

El problema que enfrenta es que la respuesta que está enviando aún es incompleta. Aunque vacíe lo que haya en los búferes al navegador, aún depende del navegador esperar el final de la respuesta o procesar lo que tiene hasta ahora, de ahí la diferencia entre los navegadores.

Lo que es aún peor es que puede esperar el mismo comportamiento de algunos concentradores de nodos intermedios, cortafuegos, etc. ubicados en Internet entre su servidor y el navegador.

La conclusión es que si desea asegurarse de que el navegador haga algo con su flujo de datos, debe completarlo con Response.End.

En otras palabras, si desea enviar primero algunos de sus datos de respuesta y retrasar el envío del resto, su mejor opción es dividir la respuesta en dos, completar la primera y descargar la segunda parte por separado

Otros consejos

Una manera fácil de resolver esto es colocar un & "; Por favor espere, procesando &"; página en frente de la página real que hace el trabajo. El & Quot; por favor espere & Quot; se muestra el mensaje e inmediatamente comienza a procesarse mediante el uso de una etiqueta de meta actualización o JavaScript para redirigir a la página de procesamiento real.

" Espere " Página:

<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>

Notas:

  1. El uso de dos métodos para iniciar el procesamiento se realiza para garantizar que si un navegador no puede usar uno, con suerte usará el otro método.
  2. Tendrá que reemplazar la url de procesamiento y la cadena de consulta para adaptarse.
  3. Una desventaja de este método es que si el usuario presiona el botón de retroceso del navegador, volverá a " espere " página de " proceso " página, lo que significa que accidentalmente iniciará el trabajo nuevamente. ¡Dejaré ese desafío para otro tema!

Además, tenga en cuenta que si su servidor IIS está comprimiendo la salida con GZIP, parecerá ignorar todas las Response.Flush llamadas.

Esto está activado por defecto en IIS7 y en Windows 7.

Y, si está probando con Fiddler, asegúrese de activar " Streaming " modo, o Fiddler recopilará el HTML vaciado y lo mantendrá hasta que se complete la conexión.

Cuando llama a Response.Flush () antes de que se complete la respuesta (antes de que se conozca Content-Length), el tiempo de ejecución de ASP.NET genera una respuesta parcial de codificación fragmentada. Depende del navegador decidir cómo representar eso. En mis pruebas, descubrí que los navegadores tienden a representar imágenes (<img> etiquetas) que se incluyen en una respuesta parcial. Puede intentarlo.

Sin embargo, tenga cuidado al enviar </html> demasiado pronto; los navegadores pueden ignorar cualquier cosa que haya pasado ese punto. Sin embargo, los navegadores representan páginas parciales todo el tiempo, por lo que puede comenzar con el comienzo de su página como de costumbre.

En caso de que sea útil, reviso un ejemplo de esto en detalle en mi libro, que incluye un seguimiento de paquetes que muestra exactamente lo que sucede en el cable: ASP.NET ultrarrápido .

Creo que los navegadores obtienen y usan el contenido en función de su longitud, por lo que puede intentar rellenar 1000 caracteres más o menos. Por ejemplo:

string myVeryShortMessage = " Procesando ... " ;;

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

System.Threading.Thread.Sleep (5000);

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top