2009-06-18 24 views
18

En el código de abajo, a veces someFunctionCall() genera una excepción "Thread estaba siendo abortado". ¿Cómo es que el código en el bloque de código B nunca se ejecuta? ¿ASP.NET inicia un nuevo hilo para cada llamada de método? Me sorprendió ver que cuando ocurre esta excepción, el código en el bloque b nunca se ejecuta, el método retorna y mi aplicación sigue ejecutándose. ¿Puede alguien por favor explicar esto?ASP.NET excepción "Thread estaba siendo abortado" provoca método para salir

Gracias.

public void method() 
{ 
    // CODE BLOCK A 
    //... 


    try 
    { 
     someFunctionCall(); // this call is generating thread abort exception 
    } 
    catch(Exception ex) 
    { 
     // log exception message 
    } 

    // CODE BLOCK B 
    // ... 

} 

Respuesta

29

Esto es ThreadAbortException; es una excepción especial que se vuelve a lanzar automáticamente al final de cada bloque catch, a menos que llame al Thread.ResetAbort().

Métodos de ASP .Net como Response.End o Response.Redirect (a menos que pase false) eche esta excepción al procesamiento final de la página actual; su someFunctionCall() probablemente está llamando a uno de esos métodos.

ASP .Net misma se encarga de esta excepción y llama ResetAbort continuar su procesamiento.

+1

Entonces, ¿cómo podría conseguir hacer caso omiso de dicha excepción y continúe ejecutando el código en el bloque B? –

+0

¿Estás seguro de que quieres? Si someFunctionCall está redireccionando o terminando la respuesta, probablemente no debería continuarlo – SLaks

+0

¿Qué hace algún FunctionCall? – SLaks

-2

Trate de esta manera:

Este es mi método de extensión:

public static void WriteJSONObject(this HttpResponse response, object content) { 
      response.ContentType = "application/json"; 
      response.Write(new JavaScriptSerializer().Serialize(content)); 
      response.End(); 

} 

Y la lógica:

public void RegisterUser() { 
    try { 
     Response.WriteJSONObject(new { Result = "See hello" }); 
    } 
    catch (Exception err) { 
     if (err.Message != "Thread was being aborted.") 
      Response.WriteJSONObject(new { Result = err.Message }); 
     else { 
      Response.End(); 
     } 
    } 
} 
+11

Esto está mal. Nunca deberías comparar el 'Mensaje' de una excepción con una cadena codificada. En cambio, puede escribir 'catch (ThreadAbortException) {} catch (Exception ex) {...}'.Además, no tiene sentido llamar a 'Response.End' si ya hay una' ThreadAbortException'. – SLaks

+0

Está funcionando bien, incluso parece estar mal. – Tarik

+0

P.s: Las soluciones anteriores no funcionaron para mí como la mayoría de las personas. No importa lo que hice, no funcionó, así que esta es la única solución que he encontrado y funciona muy bien. – Tarik

1

Para evitar este problema, utilice uno de los siguientes métodos: Para Response.End, llame al HttpContext.Current.ApplicationInstance.CompleteRequest método en lugar de Response.End para eludir la ejecución del código para el evento Application_EndRequest.

Para Response.Redirect, utilice una sobrecarga, Response.Redirect(String url, bool endResponse) que pasa false para el parámetro endResponse para suprimir la llamada interna a Response.End. Por ejemplo:

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

Si se utiliza esta solución, el código que sigue se ejecuta Response.Redirect. Para Server.Transfer, use el método Server.Execute en su lugar.

Cuestiones relacionadas