2009-11-27 8 views
5

Sto cercando di trasmettere alcuni contenuti al cliente prima di fare un po 'di un lungo lavoro:Response.Flush() funziona solo con Firefox

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 si aspetta fino a quando tutto il codice viene elaborato e quindi mostra l'intero testo.

ho cercato di inviare un HTML meglio formata come l'esempio riportato di seguito, ma io ottenere 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!

risposta

2

Il problema che si sta affrontando è che la risposta che si sta inviando è ancora incompleta. Anche se scarichi tutto ciò che è presente nei buffer del browser, è comunque compito del browser attendere la fine della risposta o elaborare ciò che ha ottenuto finora, quindi la differenza tra i browser.

Ciò che è ancora peggio è che ci si può aspettare lo stesso comportamento da alcuni concentratori di nodi intermedi, firewall, ecc. Che si trovano su Internet tra il server e il browser.

La linea di fondo è che se si desidera assicurarsi che il browser faccia qualcosa con il proprio flusso di dati, è necessario completarlo con Response.End.

In altre parole se si desidera inviare alcuni dei vostri dati di risposta prima e ritardo di invio il resto la vostra opzione migliore è quello di rompere la risposta in due, completa il primo e scaricare la seconda parte separatamente

+0

Quindi AJAX è l'unico modo per farlo? –

+0

Puoi giocare qualche altro trucco: IFrame è uno, ma ajax è il più forte e con framework come JQuery non dovrebbe essere una sfida per implementare – mfeingold

3

Un facile per risolvere questo problema è necessario posizionare una pagina "Please wait, processing" davanti alla pagina effettiva che fa il lavoro. Il messaggio "please wait" viene visualizzato e quindi inizia immediatamente l'elaborazione utilizzando un tag meta refresh e/o javascript per reindirizzare alla pagina di elaborazione effettiva.

pagina "Attendere prego":

<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. utilizzando due metodi per dare il via al trattamento viene fatto per garantire se un browser non può utilizzare uno, si spera utilizzare l'altro metodo.
  2. Sarà necessario sostituire l'UI di elaborazione e la QueryString.
  3. Uno svantaggio di questo metodo è che se l'utente preme il pulsante Indietro del browser, tornerà alla pagina "Please wait" dalla pagina "processo", il che significa che accidentalmente darà nuovamente il via al lavoro. Lascerò quella sfida per un altro argomento!
+0

Eccellente! facile e semplice ... Ho appena messo in su la tua risposta perché la domanda era perché Flush() non funzionava, ma la tua risposta mi ha aiutato molto. Grazie! –

+0

Grazie =) Come dice mfeingold, la risposta viene cancellata, il problema si trova nei browser, poiché decidono quando renderanno ciò che è stato ricevuto finora. Da qui la mia idea, che garantisce che tutta la pagina Please Wait sia ricevuta e quindi sottoposta a rendering prima dell'inizio dell'elaborazione. Le gioie della programmazione web! – Will

2

Quando si chiama Response.Flush() prima che la risposta sia completa (prima che Content-Length sia nota), il runtime di ASP.NET genera una risposta parziale di codifica chunked. Spetta al browser decidere come renderlo. Nel mio test ho riscontrato che i browser tendono a visualizzare immagini (tag <img>) incluse in una risposta parziale. Potresti provare.

Tuttavia, fare attenzione all'invio di </html> troppo presto; i browser possono ignorare qualsiasi cosa oltre quel punto. Tuttavia, i browser eseguono il rendering di pagine parziali in ogni momento, quindi puoi iniziare come al solito dall'inizio della pagina.

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

+0

Tappo senza vergogna. +1. –

3

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

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

E, se si sta testando con Fiddler, assicurarsi di attivare la modalità "streaming", o Fiddler raccoglierà il codice HTML lavata e tenerlo fino al completamento della connessione.

0

Penso che i browser ottengano e utilizzino il contenuto in base alla sua lunghezza, quindi si può provare a riempire 1000 caratteri all'incirca. Ad esempio:

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

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

System.Threading.Thread.Sleep (5000);

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

Problemi correlati