2011-01-10 10 views
9
catch (ThreadAbortException) 
{ } 
catch (Exception ex) 
{ 
    TraceManager.TraceException(ex, 
           (int)ErrorCode.GENERIC_EXCEPTION, 
           ex.StackTrace + "\n" + ex.Message + "\n" + VendorUrl); 
} 

¿Tiene sentido que incluso tienen el¿Tiene sentido atrapar ThreadAbortException y no realizar ninguna acción?

catch (ThreadAbortException) 
{ } 

o voluntad que hacen que el ThreadAbortException a ser tragadas y perdido para siempre?

+4

'ThreadAbortException' se volverá a ejecutar al finalizar el controlador. – Gabe

Respuesta

29

ThreadAbortException no se puede capturar "completamente"; se volverá a lanzar automáticamente al final del bloque catch (consulte la página de documentos MSDN enlazados) a menos que se llame primeroThread.ResetAbort.

Por lo tanto, la única sensata catch bloque sería:

catch (ThreadAbortException) 
{ 
    // possibly do something here 
    Thread.ResetAbort(); 
} 

Pero esto tiene un olor muy mal. Probablemente no haya ninguna razón para hacerlo, por lo que es posible que desee replantearse su enfoque.

Actualización: Hay muchas preguntas sobre SO que tienen que ver con: Thread.Abort

This one tiene la misma respuesta que he dado aquí. This one tiene una respuesta que se expande en "no llamar nunca Thread.Abort a menos que Cthulhu esté en aumento" (que disminuyó considerablemente a un "olor maligno").

También hay muchos más.

+1

+1: redacción nit-pick. Se puede atrapar, solo se volverá a lanzar. – Hogan

+0

@Hogan: reescrito un poco; ahora el significado debería ser más claro. – Jon

+0

Muy buena respuesta. Le daría otro +1 si pudiera. – Hogan

4

ThreadAbortException no se puede detectar así. Se volverá a lanzar automáticamente al final del bloque catch a menos que llame a Thread.ResetAbort();

Tener un bloque catch como el que tiene aquí para ThreadAbortException permite que se vuelva a lanzar automáticamente sin que el bloque catch (Exception) intente manejarlo.

-3

Se atrapará y perderá. En realidad, solo debería capturar excepciones con las que pueda hacer algo o que inicie sesión y luego vuelva a lanzar (con throw, no throw new [alguna excepción];).

0

Si desea hacer algo específico para diferentes tipos de excepciones, entonces tiene que tener bloques de captura independientes. De lo contrario, sólo puede utilizar la captura una excepción

+3

No estoy de acuerdo. Por lo general, es mejor ser específico sobre lo que está atrapando.Creo que si no sabe qué tipo de excepciones puede arrojar su bloque "try", significa que no le ha dado suficientes pruebas a su aplicación. –

+0

Estoy de acuerdo Ilya. +1 – Nick

0

Calling Thread.Abort en un hilo establece efectivamente una bandera que provocará una ThreadAbortException a ser arrojado ningún código de tiempo no está procesando esa excepción ni asociado finally bloques. Capturar la excepción sin llamar al Thread.ResetAbort() simplemente dará como resultado que el tiempo de ejecución arroje otro ThreadAbortException en su próxima oportunidad. Sin embargo, tal comportamiento no es completamente sin sentido, ya que hará que todos los bloques internos finally se ejecuten hasta su finalización antes de que la excepción se pueda ver mediante bloques externos de filtro de excepciones. Si eso es algo bueno o no dependerá de la aplicación.

Cuestiones relacionadas