Nestes últimos 2 dias eu perdi um tempo impressionante com algo que em tese deveria ter sido extremamente simples de fazer, tipo 5 minutos… A idéia era fazer um página que iria rodar uma operação longa ir mostrando o andamento da operação, algo como “Passo 1 executado”, “Passo 2 executado” e assim por diante…
Como a regra de negócio estava pronta, achei que fosse trivial ir gerando as tags <p> e ir mostrando o andamento com flushs… Não poderia estar mais errado! Inicialmente tentei usar o HtmlWriter do Render pra ir fazendo os Writes intercalados com os Response.Flush() (fiz um teste com Sleep() pra simular o processamento). Mas não funcionou, ele mostrava a página só no final, com todos os passos de uma vez.
Aí comecei o processo conhecido de buscar no google alguma dica ou esperiência pra entender o que estava errado. Nem precisa falar que o help da MSDN era inútil, aliás copiei e colei o exemplo deles e mesmo comportamento. Comecei a ver que este é um problema para muitas pessoas, aparentemente em algumas situações o Response.Flush() simplesmente não funciona e um mesmo código que funciona para um (como o exemplo da MSDN) não funciona pra outros.
Claro que deve ter algo na página ou no ambiente que faz com que este probelma apareça. Gastei umas boas 4 horas tentando eliminar o que era, utilizando as dicas que achei de pessoas no google para tentar mapear o que era. Mas a questão é que parecia que vários tipos de problemas acabavam se sobrepondo, o principal sendo um próprio entendimento do que o Flush() deveria fazer. Na minha visão (e na visão de várias pessoas que eu vi), ele deveria simplesmente fazer com que o conteúdo gerado até ali fosse para o browser. Mas até sobre isto haviam dúvidas. E aí vinham várias receitas, pra ligar ou desligar buffer, pra fazer com código <% %> intercalado na página ou em determinado evendo em code-behind e até para fazer várias vezes em sequência o comando Flush() para que ele funcionasse! Nenhuma alternativa funcionou pra mim, fui dormir para tentar de novo no dia seguinte.
No dia seguinte, mais 2h. O tempo gasto nisto já estava absurdo e poderia até ter feito com javascript simples, mas vocês sabem, vira questão de honra! Continuando as busca no google, achei um comentário dizendo que uma instrução específica, faria toda a diferença: Response.BufferOutput = false. E neste cenário, realmente funcionou, mas somente no código aspx direto! Já que neste caso estava funcionando, comecei a tentar isolar o que realmente causava o probelma. Mas não tive sucesso, qualquer pequena alteração fazia com que o código deixasse de funcionar. Desisti, o código final ficou desta forma:
—————————————————————————————————————–
Enfim, é impressionante como perdemos tempo com coisas triviais. Esta do Response.Flush é mais um exemplo. Fazer software é muito bom, mas este tipo de coisa não é muito!
#1 por Diogo Menezes em 28/05/2010 - 12:12 pm
Fala Alexandre, estou passando pelo mesmo problema que você.
É realmente ridículo isso não funcionar.
O meu cenário é implementar uma progressbar em asp net…
Tenho 2 classes com o padrão observer funcionando e avisando as modificações, mas infelizmente não consigo atualizar a página como flush.
Tentei com update panel + label e também não funciona 😦
Uma coisa que eu reparei é que se você ser um refresh (f5) em uma página com o flush no CS, ela incrivelmente funciona !!!!
#2 por Alexandre Valente em 30/05/2010 - 6:43 am
Complicado mesmo…. O melhor aí acho que é montar algo que possa ser chamado pelo client side e fazer tudo em jscript.
#3 por Flavio Chapela em 23/01/2011 - 6:36 pm
Realmente essa operação é um terror.
Recentemente passei por um problema parecido, e descobri que parte dele provem do IIS. Ao dar o primeiro flush ele apaga os Headers da pagina, ou seja, na primeira descarga o navegador deixa de saber que tipo de documento esta sendo retornado, entao ele espera a conclusao do processamento para poder dar o retorno correto.
Experimente dar um flsh inicial, em sequencia adicionar via codigo os cabeçalhos da pagina, Ex:
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;
Response.ContentType = “Tipo de retorno”;
Response.AddHeader(“cabeçalhos adicionais”);
Att Flavio