Domanda

Sto cercando di inviare alcuni contenuti al client prima di fare un lungo lavoro:

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

In Firefox funziona come previsto, ma in IE8, Safari e Chrome attende fino a quando non viene elaborato tutto il codice e quindi mostra l'intero testo.

Ho provato a inviare un HTML meglio formato come nell'esempio seguente ma ottengo gli stessi risultati:

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

Grazie!

È stato utile?

Soluzione

Il problema che stai riscontrando è che la risposta che stai inviando è ancora incompleta. Anche se scarichi qualsiasi cosa sia nei buffer nel browser, spetta comunque al browser attendere la fine della risposta o elaborare ciò che è arrivato finora, da qui la differenza tra i browser.

La cosa peggiore è che puoi aspettarti lo stesso comportamento da alcuni concentratori di nodi intermedi, firewall, ecc. che si trovano su Internet tra il tuo server e il browser.

La linea di fondo è che se vuoi assicurarti che il browser faccia qualcosa con il tuo flusso di dati devi completarlo con Response.End.

In altre parole, se si desidera inviare prima alcuni dei dati di risposta e ritardare l'invio del resto, l'opzione migliore è quella di interrompere la risposta in due, completare la prima e scaricare la seconda parte separatamente

Altri suggerimenti

Un modo semplice per risolvere questo problema è di inserire un " Attendere, elaborazione " pagina davanti alla pagina effettiva che fa il lavoro. Il & Quot; attendere & Quot; viene visualizzato il messaggio e inizia immediatamente l'elaborazione utilizzando un tag meta refresh e / o javascript per reindirizzare alla pagina di elaborazione effettiva.

" Attendere " Pagina:

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

Note:

  1. L'utilizzo di due metodi per dare il via all'elaborazione viene eseguito per garantire che se un browser non può utilizzarne uno, si spera che utilizzi l'altro metodo.
  2. Dovrai sostituire l'URL di elaborazione e la stringa di query per adattarli.
  3. Uno svantaggio di questo metodo è che se l'utente preme il pulsante Indietro del browser, tornerà alla " attendere " pagina dalla " process " pagina, il che significa che avvierà di nuovo accidentalmente il lavoro. Lascerò quella sfida per un altro argomento!

Inoltre, tieni presente che se il tuo server IIS sta comprimendo l'output con GZIP, sembrerà ignorare tutte le Response.Flush chiamate.

Questo è attivato per impostazione predefinita in IIS7 e su Windows 7.

E, se stai testando con Fiddler, assicurati di attivare " Streaming " mode, o Fiddler raccoglierà il codice HTML scaricato e lo manterrà fino al completamento della connessione.

Quando si chiama Response.Flush () prima che la risposta sia completa (prima che sia nota Content-Length), il runtime ASP.NET genera una risposta parziale con codifica a blocchi. Sta al browser decidere come renderlo. Nei miei test ho scoperto che i browser tendono a rendere le immagini (<img> tag) incluse in una risposta parziale. Puoi provarlo.

Tuttavia, fai attenzione a inviare </html> troppo presto; i browser possono ignorare qualsiasi cosa oltre quel punto. I browser eseguono comunque il rendering di pagine parziali in ogni momento, quindi puoi iniziare con l'inizio della pagina come al solito.

Nel caso sia utile, passo attraverso un esempio di questo in dettaglio nel mio libro, tra cui una traccia di pacchetto che mostra esattamente cosa succede sul filo: Ultra-Fast ASP.NET .

Penso che i browser ottengano e utilizzino il contenuto in base alla sua lunghezza, quindi potresti provare a riempire circa 1000 caratteri. Ad esempio:

stringa myVeryShortMessage = " Elaborazione in corso ... " ;;

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

System.Threading.Thread.Sleep (5000);

Response.Write (& Quot; quot Fine &; .PadRight (1000)); Response.Flush ();

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top