Response.Flush () só funciona com Firefox
-
05-07-2019 - |
Pergunta
Eu estou tentando enviar algum conteúdo para o cliente antes de fazer algum trabalho demorado:
Response.Write("Processing...");
Response.Flush();
System.Threading.Thread.Sleep(5000);
Response.Write("Finish");
Response.End();
No Firefox funciona como esperado, mas no IE8, Safari e Chrome espera até que todo o código é processado e, em seguida, mostra todo o texto.
Eu tentei enviar um HTML melhor formado como o abaixo da amostra, mas eu obter os mesmos 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();
Obrigado!
Solução
O problema que você está enfrentando é que a resposta que você está enviando ainda está incompleta. Mesmo que você lave tudo quanto existe nos buffers para o navegador, ainda é até o navegador para esperar o fim de resposta ou processo que ele tem até agora - daí a diferença entre os navegadores.
O que é ainda pior é que você pode esperar o mesmo comportamento de alguns nós concentradores intermédios, firewalls, etc. localizado na Internet entre o servidor eo navegador.
A linha inferior é que se você quiser garantir que o navegador faz algo com transmitir seus dados você tem que completar com Response.End.
Em outras palavras, se você quiser enviar alguns de seus dados de resposta em primeiro lugar e atrasar o envio da descansar a melhor opção é para quebrar a resposta em dois, completar o primeiro e baixar a segunda parte separadamente
Outras dicas
Uma maneira fácil de resolver isso é colocar uma página "Aguarde, processando" na frente da página real que faz o trabalho. O "aguarde" é exibida e, em seguida, ele imediatamente começa a processar usando uma meta tag de actualização e / ou javascript para redirecionamento para a página de processamento real.
"Please Wait" 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:
- Usando dois métodos para iniciar o processamento é feito para garantir se um navegador não pode usar um, ele venha a usar outro método.
- Você terá que substituir o url processamento e querystring para o exemplo.
- Uma desvantagem deste método é que se o usuário pressiona o botão do navegador de volta, eles estarão de volta para a página de "aguarde" a partir da página "processo" vai, o que significa que vai acidentalmente lançar o trabalho novamente. Vou deixar que desafio para outro tópico!
Além disso, estar ciente de que se o servidor IIS está comprimindo a saída com GZIP, então ele vai parecem ignorar todas as chamadas Response.Flush
.
Esta é ativado por padrão no IIS 7 e no Windows 7.
E, se você está testando com Fiddler, certifique-se de transformar em "streaming" modo, ou Fiddler irá recolher o HTML corada e segurá-la até que a conexão seja concluída.
Quando você chama Response.Flush () antes que a resposta é completo (antes de Content-Length é conhecido), o tempo de execução ASP.NET gera uma resposta parcial fragmentada de codificação. É até o navegador para decidir como tornar essa. Em meus testes descobri que navegadores tendem a processar imagens (tags <img>
) que estão incluídos em uma resposta parcial. Você pode dar um que tente.
No entanto, ter cuidado com o envio </html>
cedo demais; browsers podem ignorar qualquer coisa além desse ponto. Browsers fazer processar páginas parciais todo o tempo, embora - para que você possa começar com o início de sua página, como de costume
No caso de ser útil, eu ando através de um exemplo disso em detalhe no meu livro, incluindo um rastreamento de pacotes que mostra exatamente o que acontece no fio: Ultra-fast ASP.NET .
Eu acho que navegadores obter e usar o conteúdo com base em seu comprimento, assim você pode tentar estofamento 1000 caracteres ou menos. Por exemplo:
string myVeryShortMessage = "Processamento ...";
Response.Write (myVeryShortMessage.PadRight (1000)); Response.Flush ();
System.Threading.Thread.Sleep (5000);
Response.Write ( "Finish" .PadRight (1000)); Response.Flush ();