Este artículo de KB dice que ASP.NET Response.End()
aborta un hilo.
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, Response.End()
no se ejecutará ningún código en la aplicación siguiente , y eso viola el principio de mínimo asombro. Es casi como Application.Exit()
en una aplicación WinForms. El hilo de aborto causado por la excepción Response.End()
no es capturable, por lo que rodea el código en un try
... finally
no va a satisfacer.
Me hace preguntarme si siempre debería evitarlo Response.End()
.
¿Alguien puede sugerir cuándo debo usar Response.End()
cuándo Response.Close()
y cuándo HttpContext.Current.ApplicationInstance.CompleteRequest()
?
ref: entrada del blog de Rick Strahl .
Según la información que he recibido, mi respuesta es Sí, Response.End
es dañino , pero es útil en algunos casos limitados.
- utilícelo
Response.End()
como un tiro inalcanzable, para terminar inmediatamenteHttpResponse
en condiciones excepcionales. Puede ser útil durante la depuración también. EviteResponse.End()
completar respuestas de rutina . - use
Response.Close()
para cerrar inmediatamente la conexión con el cliente. Según esta publicación 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
hace que la canalización de ASP.NET salte alEndRequest
evento una vezHttpApplication
que se complete el evento actual . Entonces, si llamaCompleteRequest
y luego escribe algo más en la respuesta, la escritura se enviará al cliente.
Editar - 13 de abril de 2011
Más claridad está disponible aquí:
- Publicación útil en el blog de MSDN
- Análisis útil de Jon Reid
Response.End
ThreadAbortException
muy bien.Response.Redirect
yServer.Transfer
ambos llamanResponse.End
y también deben evitarse.Respuestas:
Si ha empleado un registrador de excepciones en su aplicación, se diluirá con los
ThreadAbortException
s de estasResponse.End()
llamadas benignas . Creo que esta es la forma en que Microsoft dice "¡Ya basta!".Solo lo usaría
Response.End()
si hubiera alguna condición excepcional y no fuera posible realizar ninguna otra acción. Quizás entonces, registrar esta excepción podría indicar una advertencia.fuente
TL; DR
Por MSDN, Jon Reid y Alain Renon:
Rendimiento de ASP.NET - Gestión de excepciones - Escribir código que evite excepciones
Solución ThreadAbortException
Response.End y Response.Close no se utilizan en el procesamiento normal de solicitudes cuando el rendimiento es importante. Response.End es un medio conveniente y pesado para finalizar el procesamiento de solicitudes con una penalización de rendimiento asociada. Response.Close es para la terminación inmediata de la respuesta HTTP en el nivel IIS / socket y causa problemas con cosas como KeepAlive.
El método recomendado para finalizar una solicitud ASP.NET es HttpApplication.CompleteRequest. Tenga en cuenta que la representación de ASP.NET deberá omitirse manualmente ya que HttpApplication.CompleteRequest omite el resto de la canalización de la aplicación IIS / ASP.NET, no la canalización de la página ASP.NET (que es una etapa en la canalización de la aplicación).
Código
Copyright © 2001-2007, C6 Software, Inc lo mejor que pude ver.
Referencia
HttpApplication.CompleteRequest
Respuesta Fin
Respuesta Cerrar
fuente
Esta pregunta aparece cerca de la parte superior de todas las búsquedas de Google para obtener información sobre la respuesta. Para otras búsquedas como yo que desean publicar CSV / XML / PDF, etc. en respuesta a un evento sin mostrar toda la página ASPX, así es como lo hago. . (anular los métodos de renderizado es demasiado complejo para una tarea tan simple como OMI)
fuente
Sobre la pregunta "Todavía no sé la diferencia entre Response.Close y CompleteRequest ()", diría:
Prefiere CompleteRequest (), no use Response.Close ().
Consulte el siguiente artículo para obtener un resumen bien hecho de este caso.
Tenga en cuenta que incluso después de llamar a CompleteRequest (), se agregará texto (por ejemplo, redirigido del código ASPX) a la secuencia de salida de respuesta. Puede evitarlo anulando los métodos Render y RaisePostBackEvent como se describe en el siguiente artículo .
Por cierto: estoy de acuerdo con evitar el uso de Response.End (), especialmente al escribir datos en la secuencia http para emular la descarga de archivos. Hemos utilizado Response.End () en el pasado hasta que nuestro archivo de registro se llenó de ThreadAbortExceptions.
fuente
No estoy de acuerdo con la afirmación " Response.End es perjudicial ". Definitivamente no es dañino. Respuesta. Fin hace lo que dice; finaliza la ejecución de la página. El uso del reflector para ver cómo se implementó solo debe verse como instructivo.
Mi recomendación de 2cent
EVITE usarla
Response.End()
como flujo de control.DO uso
Response.End()
si es necesario para detener la ejecución petición y ser consciente de que (por lo general) * sin código se ejecutará allá de ese punto.*
Response.End()
y ThreadAbortException s.Response.End()
lanza una ThreadAbortException como parte de su implementación actual (como lo señala OP).Para ver cómo escribir código que debe tratar con ThreadAbortExceptions, consulte la respuesta de @ Mehrdad a SO ¿Cómo puedo detectar una excepción de amenaza de amenaza en un bloque finalmente donde hace referencia a RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup Method y Restrained Execution Regions?
El artículo de Rick Strahl mencionado es instructivo, y asegúrese de leer los comentarios también. Tenga en cuenta que el problema de Strahl fue específico. Quería llevar los datos al cliente (una imagen) y luego procesar la actualización de la base de datos de seguimiento de visitas que no ralentizara el servicio de la imagen, lo que hizo que su problema fuera hacer algo después de la respuesta.
fuente
Nunca he considerado usar Response.End () para controlar el flujo del programa.
Sin embargo, Response.End () puede ser útil, por ejemplo, cuando sirve 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.
fuente
He usado Response.End () tanto en .NET como en ASP clásico para terminar con fuerza las cosas antes. Por ejemplo, lo uso cuando hay una cierta 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):
Al entregar archivos a un usuario, usaría un Flush, el Fin puede causar problemas.
fuente
Solo he usado Response.End () como mecanismo de prueba / depuración
A juzgar por lo que ha publicado en términos de investigación, diría que sería un mal diseño si requiriera respuesta.
fuente
En asp clásico, tenía un TTFB (Time To First Byte) de 3 a 10 segundos en algunas llamadas ajax, mucho más grande que el TTFB en páginas normales con muchas más llamadas SQL.
El ajax devuelto fue un segmento de HTML para ser inyectado en la página.
El TTFB fue varios segundos más largo que el tiempo de renderizado.
Si agregué una respuesta al final del render, el TTFB se redujo considerablemente.
Podría obtener el mismo efecto emitiendo un "</body> </html>", pero esto probablemente no funcione al generar json o xml; aquí se necesita respuesta.end.
fuente