Este artigo da Response.End()
Base de dados de KB diz que o ASP.NET interrompe um thread.
Refletor mostra que ele se parece com isso:
public void End()
{
if (this._context.IsInCancellablePeriod)
{
InternalSecurityPermissions.ControlThread.Assert();
Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
}
else if (!this._flushing)
{
this.Flush();
this._ended = true;
if (this._context.ApplicationInstance != null)
{
this._context.ApplicationInstance.CompleteRequest();
}
}
}
Isso parece muito duro para mim. Como o artigo da KB diz, qualquer código no aplicativo a seguir Response.End()
não será executado e isso viola o princípio de menor espanto. É quase como Application.Exit()
em um aplicativo WinForms. A exceção de cancelamento de encadeamento causada por Response.End()
não é capturável, portanto, cercar o código em try
... finally
não será satisfatório.
Isso me faz pensar se devo sempre evitar Response.End()
.
Alguém pode sugerir, quando devo usar Response.End()
, quando Response.Close()
e quando HttpContext.Current.ApplicationInstance.CompleteRequest()
?
ref: entrada no blog de Rick Strahl .
Com base nas informações recebidas, minha resposta é: Sim, Response.End
é prejudicial , mas é útil em alguns casos limitados.
- use
Response.End()
como um lançamento inalcançável, para encerrar imediatamente oHttpResponse
em condições excepcionais. Também pode ser útil durante a depuração. EviteResponse.End()
completar respostas de rotina . - use
Response.Close()
para fechar imediatamente a conexão com o cliente. Por esta postagem do blog do MSDN , esse método não se destina ao processamento normal de solicitações HTTP. É altamente improvável que você tenha um bom motivo para chamar esse método. - use
CompleteRequest()
para finalizar uma solicitação normal.CompleteRequest
faz com que o pipeline do ASP.NET pule para oEndRequest
evento, após a conclusão doHttpApplication
evento atual . Portanto, se você ligarCompleteRequest
, escreva algo mais para a resposta, a gravação será enviada ao cliente.
Editar - 13 de abril de 2011
Mais clareza está disponível aqui:
- Postagem útil no Blog do MSDN
- Análise útil por Jon Reid
Response.End
ThreadAbortException
bom.Response.Redirect
eServer.Transfer
ambos chamamResponse.End
e também devem ser evitados.Respostas:
Se você tiver empregado um criador de exceções no seu aplicativo, ele será diluído com os
ThreadAbortException
s dessasResponse.End()
chamadas benignas . Eu acho que essa é a maneira da Microsoft dizer "Pare com isso!".Eu usaria apenas
Response.End()
se houvesse alguma condição excepcional e nenhuma outra ação fosse possível. Talvez então, o registro dessa exceção possa realmente indicar um aviso.fonte
TL; DR
Por MSDN, Jon Reid e Alain Renon:
Desempenho do ASP.NET - Gerenciamento de exceções - Escreva código que evite exceções
Solução ThreadAbortException
Response.End e Response.Close não são usados no processamento normal de solicitações quando o desempenho é importante. Response.End é um meio conveniente e pesado de encerrar o processamento de solicitações com uma penalidade de desempenho associada. Response.Close é para o encerramento imediato da resposta HTTP no nível do IIS / soquete e causa problemas com coisas como KeepAlive.
O método recomendado para finalizar uma solicitação do ASP.NET é HttpApplication.CompleteRequest. Lembre-se de que a renderização do ASP.NET precisará ser ignorada manualmente, pois o HttpApplication.CompleteRequest ignora o restante do pipeline do aplicativo IIS / ASP.NET, não o pipeline da página ASP.NET (que é um estágio do pipeline do aplicativo).
Código
Copyright © 2001-2007, C6 Software, Inc da melhor forma possível.
Referência
HttpApplication.CompleteRequest
Response.End
Response.Close
fonte
Esta pergunta aparece no topo de todas as pesquisas do Google por informações sobre response.end, assim, para outras pesquisas como eu que desejam postar CSV / XML / PDF etc. em resposta a um evento sem renderizar a página ASPX inteira, é assim que eu faço . (substituir os métodos de renderização é excessivamente complexo para uma tarefa tão simples IMO)
fonte
Na questão de "Ainda não sei a diferença entre Response.Close e CompleteRequest ()", eu diria:
Prefere CompleteRequest (), não use Response.Close ().
Veja o seguinte artigo para obter um resumo bem feito deste caso.
Lembre-se de que, mesmo depois de chamar CompleteRequest (), algum texto (por exemplo, redndered do código ASPX) seria anexado ao fluxo de saída da resposta. Você pode evitá-lo, substituindo os métodos Render e RaisePostBackEvent, conforme descrito no artigo a seguir .
BTW: Concordo em impedir o uso de Response.End (), especialmente ao gravar dados no fluxo http para emular o download do arquivo. Usamos o Response.End () no passado até nosso arquivo de log ficar cheio de ThreadAbortExceptions.
fonte
Não concordo com a afirmação " Response.End é prejudicial ". Definitivamente, não é prejudicial. Response.End faz o que diz; termina a execução da página. Usar o refletor para ver como foi implementado deve ser visto apenas como instrutivo.
Minha recomendação 2cent
EVITAR usando
Response.End()
como controle fluxo.DO uso
Response.End()
se você precisa parar a execução do pedido e estar ciente de que (geralmente) * nenhum código será executado além desse ponto.*
Response.End()
e ThreadAbortException s.Response.End()
lança um ThreadAbortException como parte de sua implementação atual (conforme observado pelo OP).Para ver como escrever código que deve lidar com ThreadAbortExceptions, consulte a resposta de @ Mehrdad para SO. Como posso detectar uma threadabortexception em um bloco finalmente onde ele faz referência ao método RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup e regiões de execução restrita
O artigo de Rick Strahl mencionado é instrutivo e certifique-se de ler os comentários também. Observe que o problema de Strahl era específico. Ele queria levar os dados para o cliente (uma imagem) e depois processar a atualização do banco de dados de rastreamento de ocorrências que não atrasava a veiculação da imagem, o que tornava o problema de fazer alguma coisa após o Response.End ter sido chamado.
fonte
Eu nunca considerei usar Response.End () para controlar o fluxo do programa.
No entanto, Response.End () pode ser útil, por exemplo, ao exibir arquivos para um usuário.
Você gravou o arquivo na resposta e não deseja que mais nada seja adicionado à resposta, pois isso pode corromper o arquivo.
fonte
Eu usei Response.End () no .NET e no ASP clássico para finalizar com força antes. Por exemplo, eu o uso quando há uma quantidade certian de tentativas de login. Ou quando uma página segura está sendo acessada a partir de um login não autenticado (exemplo aproximado):
Ao veicular arquivos para um usuário que eu usaria um Flush, o final pode causar problemas.
fonte
Eu apenas usei Response.End () como um mecanismo de teste / depuração
A julgar pelo que você publicou em termos de pesquisa, eu diria que seria um projeto ruim se exigisse Response.End
fonte
No asp clássico, eu tinha um TTFB (Time To First Byte) de 3 a 10 segundos em algumas chamadas ajax, muito maior que o TTFB em páginas regulares com muito mais chamadas SQL.
O ajax retornado era um segmento de HTML a ser injetado na página.
O TTFB demorou vários segundos a mais que o tempo de renderização.
Se eu adicionasse um response.end após a renderização, o TTFB seria bastante reduzido.
Eu poderia obter o mesmo efeito emitindo um "</body> </html>", mas isso provavelmente não funciona ao gerar json ou xml; aqui response.end é necessário.
fonte