2012-05-15 28 views
6

Los usuarios de nuestra aplicación descargan un archivo adjunto al menos una vez en dos segundos durante el día.Response.End() vs HttpContext.Current.ApplicationInstance.CompleteRequest()

escenario anterior:

Estábamos usando Response.End() para cancelar la conexión con el cliente después de que el usuario descarga un archivo adjunto. Como teníamos problemas de rendimiento, comenzamos a registrar excepciones y una de las más repetidas fue la excepción de aborto de subprocesos. Como recibimos el archivo adjunto de un servicio web, tenemos que hacer algunas tareas de limpieza y tuvimos la limpieza en el bloque try-catch-finally. Después de algunas investigaciones, he entendido que cualquier código después de Response.End() no se ejecutará aunque esté en el bloque finally. ¿Está bien?

Escenario actual:

he leído el hilo de desbordamiento de pila sobre Response.End() que es perjudicial y que tiene que ser utilizado sólo cuando sea realmente necesario, por lo que decidió utilizar HttpContext ... .CompleteRequest() en su lugar. Con este código, se realiza la limpieza necesaria, pero el html que se procesa se agrega al archivo adjunto descargado. Traté de sobreescribir el Render y el RaisePostBackEvent sugeridos en el mismo artículo, pero el problema aún persiste. Cualquier idea sobre cómo resolver este problema sería útil.

Código:

HttpContext.Current.Response.Clear(); 

Response.ClearContent(); 

Response.ClearHeaders(); 

Response.AddHeader("Content-Disposition", "attachment; filename=" + 
filename); 
Response.AddHeader("Content-Length", fileContent.Length.ToString()); 
Response.ContentType = "application/octet-stream"; 
Response.BinaryWrite(fileContent); 
Response.Flush(); 
+0

No coloque los títulos con "C#" y tal. Para eso son las etiquetas. –

+1

Sure. Lo siento por eso. Acabo de empezar a publicar aquí. Me aseguraré de no repetir eso. – user1396468

Respuesta

5

Response.End tiros internamente la ThreadAbortException para matar a la solicitud - si es necesario hacer algún tipo de limpieza, esto debe ser hecho antes de se realiza la llamada a Response.End.

Response.Redirect y Response.End no interactúan bien con try/catch blocks. Entonces, en su situación, debe hacer toda su escritura lógica en el flujo de respuesta en su try/catch, luego simplemente llame al Response.End después de su bloqueo final.

+0

Gracias por la respuesta. Entiendo que funcionará, pero ¿cómo puedo deshacerme de ThreadAbortException, está llenando mis archivos de registro y probablemente acaparando algo de memoria en el servidor también? ¿Hay alguna manera de que pueda hacer esto sin Response.End()? editar: Además, si uso Response.End() después de mi bloqueo final, me estoy ejecutando en el mismo problema de que html renderizado se anexa al documento descargado. De todos modos, puedo resolver eso. Gracias por la respuesta nuevamente. – user1396468

+0

Deja de envolver el 'Response.End' en tu try/catch. 'Response.End' usa' ThreadAbortException' para finalizar la respuesta. Así es como funciona. Básicamente estás atrapando la excepción del marco. – Tejs

+0

Ok. No ajustaré Response.End() en un intento .. atrapar. Gracias por señalar eso. ¿Puedes responder a mi edición, acabo de probar el código que sugirió y tengo el problema html nuevamente? Realmente aprecio tus respuestas. gracias. – user1396468

0

Q anterior, y no estoy seguro de si ayuda, pero esencialmente hago lo mismo que en el ejemplo al crear archivos PDF para entregar al navegador. Sin embargo, al final del procesamiento, tengo lo siguiente:

Response.OutputStream.Flush() 
    Response.OutputStream.Close() 
    Response.End() 

La adición de .Close() básicamente. Parece que funciona bien en producción.

Ed: Sólo encontraron esta, haciendo mención a Close(): Is Response.End() considered harmful?

Otro enfoque para su problema es simplemente preponderantes con Page_PreRender() y poner el código de distribución de contenidos en allí (que tipo de sentido funcional). Entonces definitivamente no obtendrá ningún HTML no deseado, y no debería haber ninguna necesidad de Response.End() en absoluto.

Cuestiones relacionadas