Como eliminar la excepcion ThreadAbortException al navegar entre paginas en ASP.NET

Llevo casi 10 años trabajando con ASP.NET y me sorprendi al aprender que cada vez que se ejecuta el comando Response.Redirect(url) en ASP.NET (para navegar hacia otra pagina), el framework lanza intencionalmente una excepcion de tipo ThreadAbortException, con el unico objetivo de terminar absolutamente la ejecucion del request actual.

Como mencione, esto es intencional por parte del framework, y el articulo “Correct use of System.Web.HttpResponse.Redirect” de Thomas Marquardt explica las razones de este diseño.

Para observar esto, solo se necesita correr una aplicacion de ASP.NET en Debug Mode, y ejecutar una linea de Response.Redirect(“Default.aspx”), y observar la ventana de Output en Visual Studio; se vera lo siguiente:

A first chance exception of type ‘System.Threading.ThreadAbortException’ occurred in mscorlib.dll

An exception of type ‘System.Threading.ThreadAbortException’ occurred in mscorlib.dll but was not handled in user code 

Como la mayoria de los desarrolladores debe saber, esto es un problema porque uno de los principales lineamientos de performance en .NET es “No utilizar Exceptions para controlar el flujo de la aplicacion“. Si esto sucede en una aplicacion web con mucho trafico, el lanzar exceptions cada vez que un usuario navega de una pagina a otra, eventualmente va a afectar el desempeño de la aplicacion.

En fin, la solucion para esto es sencilla, pero hay un detalle importante que hay que tomar en cuenta. Como el articulo de Thomas M. indica, se debe de utilizar el siguiente codigo:

Response.Redirect("Target.aspx", false);

HttpContext.Current.ApplicationInstance.CompleteRequest();

Es decir, utilizamos el overload de Response.Redirect pasando false al parametro de endResponse(para evitar que el .NET framework haga la llamada interna a Response.End(), y al final indicamos que deseamos completar/finalizar el request.

El detalle importante que hay que considerar si deseamos utilizar esta manera de redireccionar para evitar la excepcion es que antes, la llamada interna a Response.End() hacia que cualquier codigo que estuviera despues de la llamada original a Response.Redirect() ya no se ejecute, y esto es algo a lo que inconscientemente muchos desarrolladores nos acostumbramos. No es nada raro ver codigo de este tipo en aplicaciones de ASP.NET:


if (!User.HasAccess()) Response.Redirect("GetOut.aspx");

SinceUserHasAccessDoThis();

Si lo hacemos de la manera nueva, pasando el overload con false, cualquier codigo en el metodo que este despues del Response.Redirect si se ejecutara.

Esto es porque era la llamada interna a Response.End() (que ahora estamos evitando) que terminaba la ejecucion del codigo. Como ahora estamos evitando esa llamada, la funcion SinceUserHasAccessDoThis() si se ejecutaria, a pesar de que el usuario no tuviera el acceso que se verifica en el metodo HasAccess().

Aparte de lograr evitar esas excepciones, aprendi que tambien es incorrecto utilizar Response.Redirect para controlar el flujo de la aplicacion, y al menos yo lo hacia inconscientemente. Si se desea evitar esas Exceptions y no se tiene el tiempo para hacer un refactor del codigo para estructurarlo correctamente, se puede arreglar utilizando un return; despues del Response.Redirect, de esta manera:


if (!User.HasAccess())
{
    Response.Redirect("GetOut.aspx", false);
    HttpContext.Current.ApplicationInstance.CompleteRequest();
    return;
}

SinceUserHasAccessDoThis();

Paginas de referencia

  1. Response.Redirect causes System.Threading.ThreadAbortException
  2. Correct use of System.Web.HttpResponse.Redirect
  3. Microsoft Support: PRB: ThreadAbortException Occurs If You Use Response.End, Response.Redirect, or Server.Transfer
  4. HttpApplication.CompleteRequest Method
  5. Is Response.End() considered harmful?
  6. Rick Strahl – Ending a Response without Response.End() Exceptions?

Espero les sirva.

Como determinar el tamaño de los objetos en Session State en una aplicacion de ASP.NET

En el proyecto en el que estoy asignado actualmente, trabajamos en una aplicacion financiera (ASP.NET WebForms) muy grande. Utilizada en varios paises por miles de usuarios, siempre estamos buscando optimizar la aplicacion lo mas que podamos.

El caso de este post en especifico, es que notamos que habia muchos objetos almacenados en Session State y teniamos curiosidad de saber el tamaño que esos objetos estaban ocupando, para saber si era un area que debiamos optimizar. En la actualidad, la memoria RAM es de los componentes mas baratos y una de las maneras mas faciles de mejorar el desempeño de una aplicacion, pero si acaso una empresa, aplicacion o equipo esta limitado en presupuesto, igual es un area que se puede mejorar.

Como siempre, en StackOverflow.com ya habia alguien que habia tenido la misma duda que nosotros, y pudimos obtener un metodo que serializa a disco los contenidos de la sesion para poder medir su tamaño. Este es el metodo:

protected void PrintSessionSize()
{
 long totalSessionBytes = 0;
 var b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
 System.IO.MemoryStream m;

 foreach (var obj in HttpContext.Current.Session)
 {
     m = new System.IO.MemoryStream();
     b.Serialize(m, obj);
     totalSessionBytes += m.Length;
 }
}

Espero que les sirva.

Que significa “Inconsistent line endings” en Visual Studio

Despues de muchos dias de que este dialogo me saliera en varias clases de C# en un proyecto en el que estoy, decidi averiguar que significaba “Inconsistent Line Endings” y que planeaba hacer Visual Studio al normalizar los line endings.

Como siempre, algun desarrollador brillante ya habria escrito sobre este problema: Jeff Atwood escribió The Great New Line Schism.

Resulta que es algo tan sencillo como que diferentes sistemas operativos utilizan diferentes caracteres para indicar el final de una linea de texto. Y como los caracteres obviamente son invisibles, no nos damos cuenta del problema hasta que abrimos ese archivo en otro sistema operativo. En mi caso, la mezcla se dio al haber pegado una linea de codigo (Un using statement…nadie deberia hacer copy/paste de codigo) en varias de mis clases. Otra posible razon es que si es un archivo compartido, las personas que estan editando el archivo esten usando diferentes sistemas operativos para abrir el archivo.

Esta animacion (tomada prestada del mismo articulo de Atwood) ilustra el problema:

Al momento de detectar que hay caracteres de newline mezclados, Visual Studio ofrece normalizarlos al estilo de Windows (CR + LF).

Asi es que desde ahora, pueden seleccionar Yes en ese dialogo…

1 2 3 4 5 6 31  Scroll to top