2010-07-06 46 views
11

Estoy creando aplicaciones web asp.net en .net 3.5 y quería saber cuándo usar y cuándo no usar bloques Try Catch Finally? En particular, la mayoría de mis capturas de prueba están relacionadas con la ejecución de procesos almacenados y rellenando campos de texto o vistas de cuadrícula. ¿Usaría Try Catch EVERYTIME cuando ejecuta un proceso almacenado y llena un control de visualización de datos?Cuándo usar y cuándo no usar Try Catch Finally

Mi bloque de código por lo general se parece a:

protected void AddNewRecord() 
    { 
     try 
     { 
      //execute stored proc 
      // populate grid view controls or textboxes 
     } 
     catch (Exception ex) 
     { 
      //display a messagebox to user that an error has occured 
      //return 
     } 
     finally 
     { } 
    } 
+0

vea también esto: http://stackoverflow.com/questions/505471/how-often-should-i-use-try-and-catch-in-c – 0x49D1

+0

Consulte el libro "CLR via C#", 3ra edición , por J. Richter. Cubre los conceptos de manejo de excepciones con gran detalle, y definitivamente es una buena referencia. – ileon

Respuesta

10

la respuesta es "depende".

Es posible que desee utilizar un try{...} catch {...} en cada operación atómica para que, si hay un problema, pueda retroceder al último estado correcto (mediante transacciones). Este puede ser uno o varios procedimientos almacenados, depende de su aplicación.

Si atrapa la excepción, asegúrese de ser explícito en cuanto a las excepciones que detecta. No debe tener catch (Exception ex) o catch(), conocido como manejo de excepción "catch all", sino que tiene en su lugar sentencias de catch específicas como catch (IndexOutOfRangeException ex) (por ejemplo).

Sin embargo, si no puede manejar la excepción o no hay nada que pueda hacer para limpiar, entonces no debe atraparla.

+0

¿Qué quiere decir con operación "atómica"? – user279521

+2

http://en.wikipedia.org/wiki/Atomic_operation –

+3

@ user279521 - "atómico" - como un átomo en el que no se puede dividir más. Puede tener una serie de pasos, pero cada paso no tiene ningún significado si se lleva a cabo por sí mismo. Por ejemplo, si arreglas un error en tu código pero eso requiere ediciones en varias clases, se dice que el registro de todos los archivos es atómico, ya que el solo registrar uno no tiene ningún significado. – ChrisF

0

La mayoría de las veces no deberías tener en cuenta las excepciones. Algunos lugares donde tiene sentido detectar una excepción, por ejemplo,

Cuando puede recuperarse de esa excepción específica. Cuando necesite registrarlo o informarlo (por ejemplo, al usuario), generalmente en el nivel superior de su código. Cuando la persona que llama de su código no puede manejar las excepciones, entonces necesita convertirlas a algún otro formato de error.

Además, la instrucción de bloqueo de uso se puede utilizar para llamar a Dispose en objetos IDisposable, lo que elimina la necesidad de intentar ... finalmente.

+0

¿Qué sucede si quiero mostrar un mensaje al usuario "Se produjo un error al cargar datos"? ¿Cómo podría lograr eso sin un bloque Try Catch? – user279521

+0

Necesita un try-catch para mostrar el cuadro de mensaje con la excepción –

+0

Como dije, solo necesita esto en el nivel superior de su código: "Cuando necesita iniciar sesión o informarla (por ej., Al usuario)) - generalmente en el nivel superior de tu código ". – Polyfun

4

Solo debe usar try catch, cuando tenga la intención de manejar la excepción en el bloque catch. Lo que quiero decir con "handle" es, registrar el error, elegir una ruta diferente debido al error, etc. Si solo tiene intención de volver a lanzarlo, no tiene sentido que intente capturar.

+1

Si desea registrar el error, no es necesario detectar la excepción en el punto donde ocurrió, sino que puede tener una captura en el punto de salida de su código que registra cualquier excepción que ocurra en cualquier parte de su código. – Polyfun

+0

Haces un buen punto, pero creo que depende en gran medida de la arquitectura general de la aplicación. Realmente solo lo estaba proporcionando como un ejemplo de cuándo usar posiblemente una captura de prueba. – kemiller2002

+0

¿Qué sucede si las invariantes de un objeto se basan en la ejecución de todo el código dentro de un bloque? Creo que, en tal caso, el código debe estar protegido por un bloque que invalidará expresamente el objeto si se produce una excepción en el momento en que las invariantes del objeto no puedan contenerse. Si la excepción hará que el código de llamada abandone el objeto dañado, la acción de abandonar el objeto dañado resolverá el problema. Si el código de llamada intenta usar el objeto corrupto, tales intentos deberían causar excepciones, lo que obligaría a que se desenrollen aún más hasta que las cosas se resuelvan o mueran por completo. – supercat

1

Como han dicho otros, depende. Yo tiendo a usar try/catch/finally bloques en dos situaciones:

  • tengo que manejar la excepción de alguna manera que no sea simplemente volver a tirarlo.

  • Necesito limpiar algunos recursos en el bloque finally.

Aparte de esas dos situaciones, dejo que el código de llamada manejar las excepciones que podrían ocurrir.

+0

Como un aparte, 'using' es básicamente un bloque' try-finally' para limpiar recursos (a través de 'Dispose'). – Brian

+0

@Brian - Correcto, pero no todo lo que necesita limpiarse siempre implementa IDisposable (o Dispose). –

1

Además de lo que otros han dicho, asegúrese de evitar hacer esto:

try 
    { 
     throw new ApplicationException("Fake sql ex"); 
    } 
    //catch and do nothing. swallowing exceptions 
    catch(Exception){ }     
+2

Manejo de excepciones de Pokemon: ¡Tengo que atraparlos a todos! –

0

¿Cuál es el Exception que se espera de la proc almacenado?Siempre que no utilice pokemon exception handling y sepa exactamente qué se espera que haga su aplicación, cualquier cosa que no se ajuste a la excepción específica que desea atrapar será capturada por el objeto Application.

En otras palabras, no utilizan o catch {}catch (Exception), pero el manejo de excepciones especializada:

catch(SqlException e) 
{ 
    // Log stacktrace and show a friendly error to your user 
} 

El evento Application.Error es donde un comportamiento inesperado debe ser capturado y es más fácil de identificar que simplemente tener un retorno al cliente para diciendo "mis campos no muestran nada".

+0

No se espera ninguna excepción en particular, pero "para estar a salvo", me dijeron en el pasado que todas las llamadas a la base de datos deberían incluirse en los bloques try catch. – user279521

+0

Pero no es necesario que capture Exception. Puede disfrutar de todas las SqlExceptions o de la base de datos que esté utilizando.Si se lanza algo más, probablemente querrás saberlo en lugar de morir en silencio. –

0

Use "try catch" dentro del ciclo interno que debería seguir ejecutándose cuando ocurre una excepción en particular. Tenga en cuenta que si tiene un ciclo que se ejecuta 10.000 veces y se produce una excepción, p. la décima repetición que no afectará a las otras 9.990 puede ser útil para atrapar la excepción y dejar que el ciclo continúe. Por otro lado, si la excepción indica un error que sugiere que los tiempos 11, 12, 13, etc. a través del ciclo también van a fallar, sería mucho más rápido permitir que la excepción matara al bucle que seguir reintentando una operación eso no va a funcionar

Cuestiones relacionadas