Es la Respuesta.End() considera perjudicial?
Este artículo de KB dice que ASP.NET ' s Response.End()
aborta un hilo.
El reflector muestra que se ve así:
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();
}
}
}
Esto me parece bastante duro. Como dice el artículo de KB, cualquier código en la aplicación que siga a Response.End()
no se ejecutará, y eso viola el principio de mínimo asombro. Es casi como Application.Exit()
en una aplicación WinForms. La excepción de interrupción del subproceso causada por Response.End()
no es catchable, por lo que rodea el código en un try
...finally
no satisfará.
Me hace preguntarme si siempre debería evitar Response.End()
.
¿Puede alguien sugerir, cuándo debo usar Response.End()
, cuándo Response.Close()
y cuándo HttpContext.Current.ApplicationInstance.CompleteRequest()
?
Ref: La entrada del blog de Rick Strahl .
Basado en la entrada que he recibido, mi respuesta es, Sí, Response.End
es perjudicial, pero es útil en algunos casos limitados.
- use
Response.End()
como un lanzamiento inalcanzable, para terminar inmediatamente elHttpResponse
en condiciones excepcionales. Puede ser útil durante depuración también. EviteResponse.End()
completar las respuestas de rutina. - use
Response.Close()
para cerrar inmediatamente la conexión con el cliente. Según esta entrada de blog de MSDN, este método no está destinado al procesamiento normal de solicitudes HTTP. Es muy poco probable que tenga una buena razón para llamar a este método. - use
CompleteRequest()
para finalizar una solicitud normal.CompleteRequest
causa la ASP.NET canalización para saltar al eventoEndRequest
, después del evento actualHttpApplication
completo. Así que si llamasCompleteRequest
, entonces escribe algo más a la respuesta, la escritura será enviada al cliente.
Editar-13 de abril de 2011
Más claridad está disponible aquí:
- Entrada útil en el Blog de MSDN
- Análisis útil de Jon Reid
8 answers
Si ha empleado un registrador de excepciones en su aplicación, se diluirá con los ThreadAbortException
s de estas llamadas benignas Response.End()
. Creo que esta es la manera de Microsoft de decir " Basta!".
Solo usaría Response.End()
si hubiera alguna condición excepcional y no fuera posible ninguna otra acción. Tal vez entonces, registrar esta excepción podría indicar una advertencia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-06 18:06:53
TL; DR
Inicialmente había recomendado que simplemente reemplazara todas sus llamadas a [Respuesta.Fin] con [...] CompleteRequest () llama, pero si desea evitar procesamiento postback y renderizado html necesitarás agregar [...] anula como bien.
Jon Reid , "Análisis final"
Por MSDN, Jon Reid , y Alain Renon:
ASP.NET Rendimiento - Gestión de Excepciones-Escribir Código Que Evita Excepciones
El Servidor.Transferencia, Respuesta.Redireccionamiento, Respuesta.Métodos de fin todas las subidas salvedad. Cada uno de estos métodos llama internamente a la Respuesta.Final. La llamada a Respuesta.End, a su vez, causa una excepción ThreadAbortException.
ThreadAbortException Solution
HttpApplication.CompleteRequest() establece una variable que hace que el hilo saltar más allá de la mayoría de los eventos en la tubería de eventos HttpApplication [not] not el Cadena de eventos de la página, pero la cadena de eventos de la aplicación.
...
Crear una variable de nivel de clase que marca si la página debe terminar y luego compruebe la variable antes de procesar sus eventos o renderizar su página. [...] Yo recomendaría simplemente anular los métodos RaisePostBackEvent y Render
Respuesta.Fin y Respuesta.Cerrar no se utilizan en el procesamiento normal de solicitudes cuando el rendimiento es importante. Respuesta.Final es un conveniente, medios de mano dura de finalización del procesamiento de solicitudes con una penalización de rendimiento asociada. Respuesta.Close es para la terminación inmediata de la respuesta HTTP en el IIS / socket nivel y causa problemas con cosas como KeepAlive.
El método recomendado para terminar un ASP.NET la solicitud es HttpApplication.Solicitud completa. Tenga en cuenta que ASP.NET el renderizado tendrá para ser omitido manualmente desde HttpApplication.CompleteRequest se salta el resto de la canalización de aplicaciones IIS / ASP. NET, no el ASP.NET Canalización de página (que es una etapa en la canalización de aplicaciones).
Código
Copyright © 2001-2007, C6 Software, Inc lo mejor que pude decir.
Referencia
HttpApplication.CompleteRequest
Causas ASP.NET para omitir todos los eventos y el filtrado en la cadena de canalización HTTP de ejecución y ejecutar directamente el evento EndRequest.
Respuesta.End
Este método es sólo para la compatibilidad con ASP - es decir, para compatibilidad con la tecnología de programación web basada en COM que precedió ASP. NET. preceded ASP.NET. [Sin cursiva en el original]
Respuesta.Cerrar
Este método termina la conexión con el cliente de manera abrupta y es no está diseñado para el procesamiento normal de solicitudes HTTP. [Énfasis añadido]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-10 20:06:17
Esta pregunta aparece cerca de la parte superior de todas las búsquedas de Google para obtener información sobre la respuesta.end so para otras búsquedas como yo que desean publicar CSV / XML / PDF, etc. en respuesta a un evento sin renderizar toda la página ASPX, así es como lo hago. (sobreescribir los métodos de renderizado es demasiado complejo para una tarea tan simple IMO)
// Add headers for a csv file or whatever
Response.ContentType = "text/csv"
Response.AddHeader("Content-Disposition", "attachment;filename=report.csv")
Response.AddHeader("Pragma", "no-cache")
Response.AddHeader("Cache-Control", "no-cache")
// Write the data as binary from a unicode string
Dim buffer As Byte()
buffer = System.Text.Encoding.Unicode.GetBytes(csv)
Response.BinaryWrite(buffer)
// Sends the response buffer
Response.Flush()
// Prevents any other content from being sent to the browser
Response.SuppressContent = True
// Directs the thread to finish, bypassing additional processing
HttpContext.Current.ApplicationInstance.CompleteRequest()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-21 10:19:53
Sobre la pregunta de "Todavía no sé la diferencia entre la Respuesta.Close and CompleteRequest()" Yo diría:
Prefiera CompleteRequest(), no use Response.Cerca().
Ver el siguiente artículo para un resumen bien hecho de este caso.
Tenga en cuenta que incluso después de llamar a CompleteRequest() algún texto (por ejemplo, redndered desde el código ASPX) se agregaría al flujo de salida de la respuesta. Puede evitarlo anulando Render y RaisePostBackEvent métodos descritos en el siguiente artículo.
Por cierto: Estoy de acuerdo con la prevención del uso de la respuesta.End (), especialmente cuando se escriben datos en el flujo http para emular la descarga de archivos. Hemos usado la Respuesta.End () en el pasado hasta que nuestro archivo de registro se llenó de ThreadAbortExceptions.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-02 15:53:45
No estoy de acuerdo con la declaración " Respuesta.End is harmful". Definitivamente no es dañino. Respuesta.End hace lo que dice; termina la ejecución de la página. El uso de reflector para ver cómo se implementó solo debe verse como instructivo.
Mi Recomendación del 2cent
EVITE usando Response.End()
como flujo de control.
HAGA use Response.End()
si necesita detener la ejecución de la solicitud y tenga en cuenta que (normalmente)* ningún código se ejecutará después de ese punto.
* Response.End()
y ThreadAbortException s.
Response.End()
lanza una ThreadAbortException como parte de su implementación actual (como se indica en OP).
ThreadAbortException es una excepción especial que puede ser capturada, pero se levantará automáticamente de nuevo al final del bloque catch.
Para ver cómo escribir código que debe tratar con ThreadAbortExceptions, vea la respuesta de @Mehrdad a SO ¿Cómo puedo detectar una threadabortexception en un bloque final donde hace referencia a RuntimeHelpers.Executecodewith Guaranteedcleanup Method and Constrained Execution Regions
El artículo de Rick Strahl mencionado es instructivo, y asegúrese de leer los comentarios también. Nótese que el asunto de Strahl era específico. Quería obtener los datos al cliente (una imagen) y luego procesar la actualización de la base de datos de seguimiento de visitas que no ralentizara la entrega de la imagen, lo que hizo que su problema fuera hacer algo después Respuesta.Fin había sido llamado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:37
Nunca he considerado usar la respuesta.End() para controlar el flujo del programa.
Sin embargo Respuesta.End() puede ser útil, por ejemplo, cuando se sirven archivos a un usuario.
Ha escrito el archivo en la respuesta y no desea que se agregue nada más a la respuesta, ya que puede dañar su archivo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-06 16:49:08
He usado Respuesta.End () tanto en.NET como en Classic ASP para terminar forzosamente las cosas antes. Por ejemplo, lo uso cuando hay una cantidad de intentos de inicio de sesión. O cuando se accede a una página segura desde un inicio de sesión no autenticado (ejemplo aproximado):
if (userName == "")
{
Response.Redirect("......");
Response.End();
}
else
{
.....
Al servir archivos a un usuario usaría un Flush, el Final puede causar problemas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-06 18:01:30
Solo he usado Respuesta.End () como mecanismo de prueba/depuración
<snip>
Response.Write("myVariable: " + myVariable.ToString());
Response.End();
<snip>
A juzgar por lo que ha publicado en términos de investigación, yo diría que sería un mal diseño si requiere Respuesta.End
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-06 18:10:00