2012-04-17 20 views
16

Sé que la declaración Using elimina el objeto que se está creando. Al igual que si lo que quería hacer algo como esto:Excepción de captura dentro Uso de la instrucción

Using(SqlConnection conn = new SqlConnection(connString)) 
    { 
     //some code 
     //How to show the users if conn is not opened up or generated some kind of error? 
    } 

Cómo los usuarios si conn no se abre o se generan algún tipo de error mostrar?

+0

Surround con un bloque TryCatch – SimpleVar

+0

Con 'try/catch '. – Jon

+0

¿Podría aclarar su pregunta? No estoy seguro de lo que estás pidiendo aquí. – Tejs

Respuesta

8

using no ofrece ninguna puerta trasera en el catch.

Simplemente se expanden de forma manual (hay razón para tener el try/catch dentro del uso de la OMI):

SqlConnection conn = null; 

try 
{ 
    conn = new SqlConnection(""); 
} 
catch ... 
{ 

} 
finally 
{ 
    if (conn != null) 
     conn.Dispose(); 
} 

estoy a favor de esto una envolviendo el using en un try-catch e incorporación de un try-catch en el using la mayor parte del Es hora de evitar que el código termine con un try-catch anidado una vez compilado. Sin embargo, si solo necesitas cubrir un subconjunto muy pequeño de un código grande dentro de un using, sería más granular y lo insertaré.

+0

@marc_s Semántica, el punto es que 'using' no ofrece ningún soporte, tienes que volver a try/catch. –

+2

@marc_s Mi manera compila solo una prueba/captura, de lo contrario cada una a su gusto. La mina no ofrece menos soporte que 'usar'. –

22

No hay nada especial sobre el código escrito dentro de un bloque using - sólo tiene que utilizar un try.catch para manejar excepciones:

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    try 
    { 
     conn.Open(); 
     // do more stuff here...... 

    } 
    catch(SqlException sqlEx) 
    { 
     // log error and possibly show to user in a MessageBox or something else 
    } 
} 

El bloque using(...) { ... } en sí está diseñado única para asegurar que el recurso/objeto que "encapsulados" se desecha adecuadamente cuando ya no se necesita. No hay nada que pueda hacer con la declaración using para que se encargue de los errores.

así que si esperas que se acaba de crear el objeto podría fallar, entonces usted tendría que poner todo el bloque using dentro del bloque try ... catch, o caer de nuevo a un bloque try ... catch ... finally y eliminación adecuada a sí mismo (como Adam sugirió en su responder).

+0

¿Por qué estamos usando try/catch inside Using? –

+5

+1 ... no solo no es especial, sino que es una buena práctica usar try/catch en un statement de uso. La eliminación de objetos y el manejo de excepciones son conceptos diferentes. –

+2

@Raj Porque un Try/Catch es la forma de atrapar una excepción. Un uso es solo un Try/Finally (sin un catch). Si su pregunta es por qué no está fuera del uso, es porque la creación de la conexión no es probable que cause un error, la apertura es. – Servy

2

Eso es exactamente lo que haría sin él.

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    try{ 
    //some code 
    } 
    catch(SqlException e) 
    MessageBox.Show(e.Message); 
} 
3

sólo de la forma habitual:

De cualquier

try 
{ 
    using(SqlConnection conn = new SqlConnection(connString)) 
    { 
     //some code   
    } 
} 
catch (Exception exc) 
{ 
    //handle error 
} 

o

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    try 
    { 
     //some code 
    } 
    catch (Exception exc) 
    { 
     //handle error 
    }     
} 
+0

¿Cuál es el punto de usar Try/Catch inside Using? –

+2

@Widor: Esto no se manejará si se lanza una excepción en 'SqlConnection conn = new ...' – xbonez

+0

Bueno, depende de lo que haga ahí; tal vez quiera capturar una excepción de potencial diferente (no relacionada con SQL) por ejemplo. – Widor

0

Usted no lo hacen en el interior del using

try 
{ 
    using(SqlConnection conn = new SqlConnection(connString)) 
    { 
     // Some code for when "conn" is succesfully instantiated 
    } 
} 
catch (SomeSpecificConnectionInstantiationException ex) 
{ 
    // Use ex to handle a bizarre instantiation exception? 
}  
+0

Puede escribir try/catch dentro del uso. ¡Creo! –

+1

Puede, pero no capturar una excepción en el uso de instanciación – Jodrell

+0

@Jodrell Pero una SqlConnection generalmente no lanzará una excepción en su constructor. La única excepción que probablemente recibirá es en la expresión del parámetro. – Servy

8
class SqlConnection 
{ 
    using(sqlConnection) 
    { 

    } 
} 

class Consumer 
{ 
    try 
    { 

    } 
    catch(SqlException) 
    { 

    } 

} 

Depende del consumidor de la clase decidir qué hacer con la excepción.

6

Como han indicado otras respuestas, solo agregue un try/catch normal.

Sin embargo, me gustaría añadir que este es el mal lugar para poner ese try/catch, especialmente si su objetivo es un mensaje "a los usuarios mostrar". Deje que la excepción ocurra en este nivel y permita que suba la pila al código que está en una mejor posición para saber cómo responder.

En otras palabras, deje su muestra de código tal como está. No agregue nada nuevo ... a ese método. Pero quizás el código que llama a este método debería estar pensando en cómo manejar una excepción ... cualquier excepción ... desde la base de datos.

+0

¿Puede mostrarme un ejemplo de eso? O cualquier enlace que sea suficiente. ¡Gracias! –

+0

@Raj Comprueba mi respuesta. Eso es lo que he mencionado en mi respuesta. – Sandeep

-2

Es una buena práctica usar try {} catch() {} dentro de la sentencia using si desea capturar una excepción lanzada por el código dentro del bloque using. Ahora, considere los siguientes dos ejemplos: eso explica por qué try-catch block dentro de la sentencia using es una buena práctica.

Ejemplo 1

 try{ 
      using(SomeObject so = new SomeObject){ 
       // Perform some tasks 
      } 
     }catch(SomeException objSomeException){ 
      // Perform some actions, if exception occurs 
     } 

Ejemplo 2

 using(SomeObject so = new SomeObject){ 
      try{  
       // Perform some tasks 
       }catch(SomeException objSomeException){ 
        // Perform some actions, if exception occurs 
       } 
     } 

Ahora, si se produce una excepción en el desempeño de algunas tareas dentro de la instrucción using, será tanto ejemplo tener la mismos resultados. La respuesta simple es no, ¿razón?

Cuando se produce una excepción en el ejemplo 1, es atrapada por el bloque de captura, sin llegar al final del bloque de uso. Por lo tanto, el someObject en el ejemplo 1 no se eliminará correctamente. Incluso si CLR es generoso (con lo que no debe contar), la memoria utilizada por someObject en el ejemplo 1 no se recuperará (o como máximo, terminará en la recolección de GC de la Generación 2).

Donde en el caso del ejemplo 2, el bloque catch está dentro de la sentencia using. Eso significa que la ejecución llegará al final del bloque de uso. Por lo tanto, su objeto será eliminado y no tendrá que preocuparse por la fuga de memoria (deterioro,

+4

Esto está mal. Si ocurre un error en el uso, el bloque implícito 'finally' del' using' desechará el objectd y la excepción será gestionada por el 'catch' externo. En el segundo caso, la excepción será gestionada por el bloque 'catch' interno, y el' finally' implícito de 'using' se deshará de él más tarde. Entonces, la única diferencia es que en la segunda muestra 'catch' el objeto aún está disponible, por lo que aún puede usarlo para manejar la excepción. En la primera muestra, el objeto ya no estará disponible en el bloque catch. No más diferencias – JotaBe

0

Cuando incrusta el bloque using() dentro de un try/catch, el bloque using() garantizará que Dispose se llama. Sin embargo, si el código no administrado en cualquier lugar dentro de su bloque de uso arroja una excepción, el uso de() se lo comerá y no alcanzará su captura. Use try/catch dentro del bloque using(), omita el uso de() y haz una prueba/captura/finalmente, o usa la extraña sintaxis "using() try" con un catch block (que te deja con un número impar de corchetes y es probable que confunda a los programadores de nivel medio que luego se encontrarán

Cuestiones relacionadas