2012-03-08 15 views
10

Esta pregunta es más de un ¿cuál es la forma correcta de hacer algo ...utilizando & try/catch anidación

La pregunta ... ¿hay una orden de anidamiento adecuado entre un bloque y una usingtry/catch?

¿Está bien anidar toda la declaración using dentro de un try/catch y mantener los beneficios de un bloque using? (¿o una excepción hará que la porción de cierre de la sentencia using se descarte en la ventana)

¿O debe anidar el try/catch dentro de las declaraciones using y rodear solo las declaraciones que hacen acceso a la base de datos?

ES ...

try { 
    using(tsmtcowebEntities db = new tsmtcowebEntities()) { 
      violationList = (from a in db.DriverTrafficViolationDetails 
          where a.DriverTrafficViolation.DriverApplicationId == DriverAppId 
          orderby a.DateOfOccurance descending 
          select a).ToList<DriverTrafficViolationDetail>(); 
      GeneralViolation = (from a in db.DriverTrafficViolations 
           where a.DriverApplicationId == DriverAppId 
           select a).FirstOrDefault(); 
    } 
} catch { } 

menos/más correcto que ...

using(tsmtcowebEntities db = new tsmtcowebEntities()) { 
    try { 
      violationList = (from a in db.DriverTrafficViolationDetails 
          where a.DriverTrafficViolation.DriverApplicationId == DriverAppId 
          orderby a.DateOfOccurance descending 
          select a).ToList<DriverTrafficViolationDetail>(); 
      GeneralViolation = (from a in db.DriverTrafficViolations 
           where a.DriverApplicationId == DriverAppId 
           select a).FirstOrDefault(); 
    } catch { } 
} 
+0

¿Realmente necesita todos los detalles de su aplicación en el código provisto? Creo que un simple ejemplo inventado sería suficiente. –

+1

El bloque de catch vacío es una práctica de programación extremadamente mala. No lo hagas! Te arrepentirás más tarde. – phoog

+0

@JonathonReinhart Para mí fue más simple copiar y pegar un bloque de código que crear un ejemplo. Inventa código cuando siento que poner el código por el mundo podría ser malo. En este caso, no veo nada negativo, ¿por qué no? – Jared

Respuesta

5

Lo posterior es mejor: evitará enmascarar las excepciones eventualmente lanzadas dy dispose. Ver esta article.

+1

+1 para señalar esto: sin embargo, cualquier Dispose que arroje una excepción ya es "malo" en mi libro :( –

+0

A menos que explícitamente quiera detectar los errores arrojados por la instrucción using. Algo así como usar (FileStream fs = new FileStream (... puede lanzar fácilmente si la ruta es inválida o inaccesible, e incluso es más probable que arroje que los contenidos de su bloque de uso. –

0

Yo sugeriría colocar el try/catch en el uso porque independientemente de si es o no es una excepción tirar debe deshacerse de los tipos el contenedor de entidad desechable

+0

Supongo que fue parte de mi pregunta. Fui 100% positivo en la funcionalidad de anidar el try/catch dentro del uso. Estaba más inseguro de si una declaración de uso podría manejar el inverso y todavía deshacerse de los objetos/recursos ... Tengo un código en el que estoy trabajando y actualmente es bidireccional. Estoy tratando de averiguar si necesito revisar el código y asegurarme de que el try/catch esté siempre anidado o no. ¡Has confirmado lo que originalmente esperaba, así que aceptaré la respuesta! @GlennFerrieLive – Jared

+0

'using' hace su propio try catch. La función 'dispose' siempre será llamada. –

+1

-1 Se llamará a Dispose independientemente de la anidación. @Jared: el uso se compila por try-finally (no try-catch como dijo J.N.). Dispose se llama en el bloque finally, por lo que se denomina si se captura o no la excepción. – phoog

2

Es realmente una cuestión de estilo y qué tan estrecho quiere mantener el alcance de db:

Si el uso está dentro del bloque try/catch, la variable db solo será accesible dentro de la porción de prueba.

Si el uso está fuera del bloque try/catch, será visible dentro de la porción de captura.

Independientemente, la variable se eliminará correctamente porque el bloque de uso es el equivalente a un try/finally.

Personalmente, me pregunto por qué necesita detectar excepciones allí y, en todo caso, qué puede hacer con ellas.

+0

Frecuentemente uso try/catch para establecer un código de estado para la respuesta en mis acciones que son llamadas a través de ajax. – Jared

1

using nidos predecible con try/catchDispose y se llamará todo en los caminos. Previsiblemente significa control siempre flujos desde el interior -> ámbitos externos (para Excepciones y retorno de flujo normal).

La pregunta es entonces: cuando caso de que el retén ser ejecutados en relación con el Disposey lo caso de que el alcance de la captura ser? La respuesta a esto variará según el código pero obviamente debe estar "en el interior" si se requiere acceso a db y "en el exterior" si el código ejecutado como parte de el using * podría ser la fuente de la excepción.

(Además, los bloques catch vacías son repulsivo! Estoy asumiendo que están ahí "para fines de demostración".)

feliz de codificación.


* Tenga en cuenta que una captura accesoria externa cogerá las excepciones lanzadas desde new tsmtcowebEntities() o (como señala J. N.) el Dispose, en caso de existir. (Es otro tema completamente si es aceptable que cualquiera de los constructores arroje una excepción ;-) Prefiero detectar excepciones lo más cerca posible de la fuente y dejar que las excepciones que no sé cómo manejar "sangren" no sean detectadas excepto en ciertas construcciones de alto nivel (por ejemplo, controladores de eventos).

+0

De hecho, tengo algunos lugares en mi código simplemente porque tengo Elmah listo para atrapar cualquier Excepción. En mi lista de cosas por hacer es volver atrás y volver a factorizar una gran cantidad de código y mis bloques de prueba/captura son una de esas áreas, así como mejorar la configuración de registro de errores que tengo. – Jared

Cuestiones relacionadas