try specific error custom create catch application c# javascript exception-handling finally

c# - specific - ¿Cuál es el propósito de "finalmente" en probar/atrapar/finalmente



try catch c# exception message (10)

En tu ejemplo, no hay mucha diferencia.

Imagina esto, sin embargo:

try { Console.WriteLine("Executing the try statement."); throw new NullReferenceException(); } catch (SomeOtherException e) { Console.WriteLine("{0} Caught exception #1.", e); } finally { Console.WriteLine("Executing finally block."); } Console.WriteLine("Executing stuff after try/catch/finally.");

En este caso, la catch no detectará el error, por lo que nunca se alcanzará nada después de todo el intento / captura / finalmente. Sin embargo, el bloque finalmente todavía se ejecutará .

La sintaxis cambiará de un idioma a otro, pero esta es una pregunta general.

¿Cuál es la diferencia entre esto ....

try { Console.WriteLine("Executing the try statement."); throw new NullReferenceException(); } catch (NullReferenceException e) { Console.WriteLine("{0} Caught exception #1.", e); } finally { Console.WriteLine("Executing finally block."); }

y esto....

try { Console.WriteLine("Executing the try statement."); throw new NullReferenceException(); } catch (NullReferenceException e) { Console.WriteLine("{0} Caught exception #1.", e); } Console.WriteLine("Executing finally block.");

Sigo viendo que se usa, así que asumo que hay una buena razón para usarlo finalmente, pero no puedo entender en qué se diferencia del hecho de poner un código después de la instrucción, ya que aún se ejecutará.

¿Hay alguna vez un escenario donde finalmente no se ejecuta?


Es una buena práctica utilizar finalmente para manejar los bloqueos de programas. finalmente siempre se ejecutará. Si la función sale dentro del bloque try catch, o si se produce otro error, ya sea en el try o en el catch, se ejecutará finalmente. No obtendrás esa funcionalidad al no utilizar la sentencia finally.


Finalmente el bloque está garantizado para ser excitado. Entonces, en tu ejemplo, los resultados de ambos casos son iguales. pero si usas return o throw en tu bloque catch, puedes ver cuál es la diferencia.


Finalmente se ejecuta tanto para tratar como para atrapar. Asegura que se ejecutará, pero no está 100% garantizado que [algunos errores detendrán la ejecución del código]


No sé C #, pero el propósito de un bloque final en lenguajes Java-ish es asegurar que los recursos del sistema se renuncien, especialmente si la recolección de basura es irregular. Es el mismo principio para todos. Considerar el bloque

InputStream is = new FileInputStream("foo.txt"); OutputStream os = new FileOutputStream("D:/nonexistent/directory/bar.txt"); // Throws a FileNotFoundException.

La variable is crea correctamente y ocupa los recursos del sistema. Los procesos solo pueden utilizar un número fijo de identificadores de archivos a la vez. La variable os nunca se crea, y se lanza una excepción, y se eleva hasta la persona que llama. En el proceso, is fuera de alcance y se vuelve elegible para la recolección de basura.

Sin embargo, las recolecciones de basura nunca se garantizan, o pueden ocurrir en un momento indefinido en el futuro. Por lo tanto, los recursos del sistema tomados por nunca pueden ser liberados. Esto puede ser costoso, o puede bloquear el programa si sucede lo suficiente. Entonces, finally se pusieron bloques en Java. Otras lenguas tienen construcciones similares. En C ++, los destructores se invocan de manera determinista. Los lenguajes LISPy tienen unwind-protect , pero generalmente se empaquetan en macros with-foo .

En Java 6 e inferior, uno haría esto:

try { is = new FileInputStream("foo.txt"); os = new FileOutputStream("D:/nonexistent/directory/bar.txt"); // work... } finally { if (is != null) { try { is.close(); } catch (IOException ignored) {} } if (os != null) { try { os.close(); } catch (IOException ignored) {} } }

No puedes simplemente llamar a is.close() porque eso podría lanzar, y el sistema is.close() nunca se cerrará. Usted tiene que comprobar para null también. Las personas IOUtils.closeQuietly() métodos IOUtils.closeQuietly() Jakarta Commons-IO para reemplazar el bloque:

} finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); }

Pero Java 7 introdujo una mejor solución: probar con recursos. C # 4 probablemente llegó primero con algo similar, Microsoft fue más rápido en la captación que Snoracle.

try ( is = new FileInputStream("foo.txt"), os = new FileOutputStream("D:/nonexistent/directory/bar.txt") ) { // work... }


Realmente depende, algunas otras respuestas tienen muy buenas razones para usar un bloque " Finally . Pero creo que la mejor razón es porque estás manejando excepciones . Las cosas que haces en un bloque Finally generalmente implican la limpieza de los recursos para asegurar una continuación adecuada, independientemente de si se lanzó una excepción o no, para mí eso sigue siendo parte del manejo de excepciones , al menos parte de una operación de "intentar algo".

En mi humilde opinión, el alcance Final resalta el hecho de que su código contiene cosas que merecen especial atención en caso de una excepción.


el bloque try necesita al menos una captura o un finally. Después de ejecutar todos los bloques catch, se ejecutará el bloque finally. Puedes agregar cualquier lógica que necesites allí, que debe hacerse en última instancia.


por fin siempre siempre corre. Finalmente es como el catcher que nunca pierde nada. En el ejemplo que mencionaste, sí, finalmente no agrega ningún valor. Pero finalmente se suele utilizar para disponer / liberar recursos.


Finalmente, debe usarse todo lo que se necesita hacer para mantener un sistema consistente. Esto usualmente significa liberar recursos.

Finalmente siempre se ejecuta, no importa qué excepción se haya lanzado. Se debe utilizar para liberar recursos, en los siguientes casos:

  • Finalizar una conexión
  • Cerrar un manejador de archivos
  • Memoria libre
  • Cerrar una conexión de base de datos

Déjame dar un ejemplo completo. Imagina que estás enviando mensajes a través de la red. En pseudocódigo:

// With finally | //Without finally try{ | try{ send_message() | send_message() } catch(NetworkError){ | } catch(NetworkError){ deal_with_exception() | deal_with_exception() } finally { | } finalizes_connection() | finalizes_connection() } |

La única diferencia de ambos códigos es cuando lo que se mantiene en el bloque try genera una excepción que no es NetworkError , por ejemplo, MethodNotFound . En el primer caso, se llamará al método finalizes_connection() , y en el segundo, no se llamará.

Una conexión se hace naturalmente a través de más de un programa. Entonces, ¿qué sucede en el caso de una excepción de MethodNotFound al otro programa? En el primer caso, su programa terminará la conexión y el otro programa y será feliz. En el segundo caso, el otro programa puede estar esperando su respuesta para siempre. ¿Qué pasa si el otro programa solo puede recibir una conexión por vez? Usted acaba de molestar el otro programa también.

Esto también se aplicaría a un archivo, por ejemplo, que abrió y otros programas no podrían abrir para leer (en Windows). Y para la memoria, nunca se libera y ahora tiene una pérdida de memoria.


try { throw new Exception("Error!"); } catch (Exception ex) { throw new Exception(ex, "Rethrowing!"); } finally { // Will still run even through the catch kicked us out of the procedure } Console.WriteLine("Doesn''t execute anymore because catch threw exception");