visual try practices net handling ejemplo catch best asp .net design-patterns exception try-catch-finally

.net - practices - try catch vba excel



¿Cuál es el punto del bloque final? (15)

Sintaxis aparte, ¿cuál es la diferencia entre

try { } catch() { } finally { x = 3; }

y

try { } catch() { } x = 3;

editar: en .NET 2.0?

asi que

try { throw something maybe x = 3 } catch (...) { x = 3 }

¿es conductualmente equivalente?


@iAn y @mats:

No eliminaría nada en finally {} que se "configuró" dentro de try {} como regla. Sería mejor extraer la creación del flujo fuera del intento {}. Si necesita manejar una excepción en la creación del flujo, esto podría hacerse en un ámbito mayor.

StreamReader stream = new StreamReader("foo.bar"); try { mySendSomethingToStream(stream); } catch(noSomethingToSendException e) { //Swallow this logger.error(e.getMessage()); } catch(anotherTypeOfException e) { //More serious, throw this one back throw(e); } finally { stream.close(); }


Bueno, para empezar, si VUELVE dentro de su bloque de prueba, finalmente se ejecutará, pero el código enumerado debajo del bloque try-catch-finally no lo hará.


Cualquier código en el finalmente se ejecuta en el incluso en caso de una excepción no controlada. Normalmente, el código finalmente se usa para limpiar declaraciones locales de código no administrado usando .dispose ().


Depende del idioma ya que puede haber algunas diferencias semánticas leves, pero la idea es que se ejecutará (casi) siempre, incluso si el código en el bloque try lanzó una excepción.

En el segundo ejemplo, si el código en el bloque catch retorna o sale, el x = 3 no se ejecutará. En el primero lo hará.

En la plataforma .NET, en algunos casos no se ejecutará el bloque finally: excepciones de seguridad, suspensiones de subprocesos, apagado de la computadora :), etc.


El bloque finally está en el mismo ámbito que el try / catch, por lo que tendrá acceso a todas las variables definidas en el interior.

Imagine que tiene un manejador de archivos, esta es la diferencia en la forma en que se escribiría.

try { StreamReader stream = new StreamReader("foo.bar"); stream.write("foo"); } catch(Exception e) { } // ignore for now finally { stream.close(); }

comparado con

StreamReader stream = null; try { stream = new StreamReader("foo.bar"); stream.write("foo"); } catch(Exception e) {} // ignore if (stream != null) stream.close();

Sin embargo, recuerde que no está garantizado que se ejecute nada por dentro. Imagina que obtienes una señal de interrupción, Windows se bloquea o la energía se ha ido. Confiar finalmente en el código crítico de la empresa es malo.


El bloque finally siempre se llamará (bien no always ...) incluso si se lanza una excepción o se llega a una declaración de devolución (aunque eso puede depender del idioma). Es una forma de limpiar que sabes que siempre se llamará.


En Java, lo utiliza para cualquier cosa que desee ejecutar, independientemente de si utilizó un "retorno", simplemente ejecutó el bloque try, o tuvo una excepción atrapada.

Por ejemplo, cerrar una sesión de base de datos o una conexión JMS, o desasignar algún recurso del sistema operativo.

¿Supongo que es similar en .NET?


En Java:

Finalmente siempre recibe una llamada, independientemente de si la excepción fue capturada correctamente en catch (), o de hecho si tiene una captura en absoluto.


En el caso, que la prueba y la captura están vacías, no hay diferencia. De lo contrario, puede estar seguro de que finalmente se ejecutará.

Si, por ejemplo, lanza una nueva excepción en su catchblock (rethrow), entonces la asignación solo se ejecutará, si está en el bloque finally.

Normalmente, finalmente se usa para limpiar después de usted (conexiones de base de datos, manejadores de archivos y "me gusta").

Nunca debe usar instrucciones de control (return, break, continue) en un final, ya que esto puede ser una pesadilla de mantenimiento y, por lo tanto, se considera una mala práctica


Entonces puede limpiar cualquier conexión abierta, etc. inicializada en el bloque try. Si abría una conexión y luego se producía una excepción, esa excepción no se cerraría correctamente. Este tipo de escenario es para lo que es el bloque finally.


Hay varias cosas que hacen que un bloque finalmente sea útil:

  1. Si regresas de los bloques try o catch, el bloque finally se sigue ejecutando, justo antes de que el control vuelva a la función de llamada
  2. Si se produce una excepción dentro del bloque catch, o si se produce un tipo de excepción no detectada en el bloque try, el código en el bloque finally se sigue ejecutando.

Esto hace que finalmente los bloques sean excelentes para cerrar los manejadores de archivos o los sockets.


Por último, los bloques le permiten, como desarrollador, ordenar después de usted mismo, independientemente de las acciones del código anterior en el bloque try {} encontrado errores, y otros lo han señalado, se encuentra principalmente bajo el paraguas de liberar recursos - cerrando punteros / sockets / conjuntos de resultados, retornando conexiones a un grupo, etc.

@mats es muy correcto en cuanto a que siempre existe la posibilidad de fallas "duras": finalmente, los bloques no deben incluir código de misión crítica, que siempre debe hacerse de forma transaccional dentro del intento {}

@mats otra vez: la verdadera belleza es que te permite volver a lanzar excepciones con tus propios métodos y, sin embargo, garantizar que arregles:

try { StreamReader stream = new StreamReader("foo.bar"); mySendSomethingToStream(stream); } catch(noSomethingToSendException e) { //Swallow this logger.error(e.getMessage()); } catch(anotherTypeOfException e) { //More serious, throw this one back throw(e); } finally { stream.close(); }

Por lo tanto, podemos detectar muchos tipos de excepciones, procesarlas de manera diferente (la primera permite la ejecución de algo más allá de la prueba {}, la segunda regresa de manera efectiva), pero siempre limpia y ordenadamente.



try catch finalmente es una construcción bastante importante. Puede estar seguro de que incluso si se lanza una excepción, se ejecutará el código en finally block. Es muy importante manejar los recursos externos para liberarlos. La recolección de basura no hará eso por usted. En la parte final, no deberías tener declaraciones de devolución ni lanzar excepciones. Es posible hacer eso, pero es una mala práctica y puede conducir a resultados impredecibles.

Si prueba este ejemplo:

try { return 0; } finally { return 2; }

El resultado será 2 :)

Comparación con otros idiomas: Return From Finally


@Ed , es posible que esté pensando en algo así como una catch(...) que atrapa una excepción no especificada en C ++.

Pero finally es el código que se ejecutará sin importar lo que ocurra en los bloques catch .

Microsoft tiene una página de ayuda en try-finally para C #