He visto a gente decir que es mala forma de uso de la captura sin argumentos, especialmente si esa captura no hacer nada:

StreamReader reader=new  StreamReader("myfile.txt");
try
{
  int i = 5 / 0;
}
catch   //No args, so it will catch any exception
{}
reader.Close();

Sin embargo, se considera que esta es una buena forma:

StreamReader reader=new  StreamReader("myfile.txt");
try
{
  int i = 5 / 0;
}
finally   //Will execute despite any exception
{
  reader.Close();
}

Medida de lo que puedo decir, la única diferencia entre poner el código de limpieza en un bloque finally y poner el código de limpieza después del try..catch bloques es que si usted tiene retorno declaraciones en su bloque try (en ese caso, el código de limpieza en la que finalmente se ejecute, pero el código después del try..catch no).

De otra manera, ¿qué es tan especial acerca de finalmente?

  • Antes de Intentar Atrapar un tigre que usted no puede manejar, usted debe documentar su Finalmente deseos.
  • Exceptions tema en la documentación puede dar algunas buenas ideas. También echa un vistazo a la por último Bloque ejemplo.
InformationsquelleAutor mbeckish | 2008-09-24

20 Comentarios

  1. 349

    La gran diferencia es que try...catch se trague la excepción, ocultando el hecho de que se ha producido un error. try..finally ejecutará su código de limpieza y, a continuación, la excepción va a seguir, a ser manejado por algo que no sabe qué hacer con ella.

    • Cualquier código escrito con la encapsulación en mente es probable que sólo es capaz de manejar la excepción en el punto donde se crió. Simplemente pasando una copia de seguridad de la pila de llamadas en la desesperada esperanza de que algo más va a ser capaz de manejar algunos arbittary excepción es una receta para el desastre.
    • Estás olvidando desactivada excepciones. Prácticamente cualquier método puede lanzar un OutOfMemoryError o algo similar. Usted quiere que su bloque finally para intentar al menos la limpieza antes de salir.
    • En la mayoría de los casos, es más evidente por qué una excepción en particular iba a ocurrir a partir del nivel de aplicación (por ejemplo, una determinada configuración) que en la clase de biblioteca de nivel.
    • David – yo preferiría que el programa falle rápido, así que puedo estar conscientes de que el problema más bien que dejar el programa funcionando en un estado desconocido.
    • Si el programa está en un estado desconocido después de una excepción, entonces usted está haciendo mal el código.
    • +1 para fallar rápido, enriquecido con finalmente
    • 3 años más tarde, esta información es difícil de obtener. Gracias!
    • cualquier código escrito con la encapsulación en mente sólo debe manejar la excepción dentro de su ámbito de aplicación. Nada más debe pasar para que alguien más manejar. Si tengo una aplicación que tiene un nombre de archivo de los usuarios, a continuación, lee el archivo, y mi lector de archivos se presenta una excepción de abrir el archivo, se debe pasar a ellos (o consumir la excepción y lanzar una nueva) para que la aplicación pueda decir, hey – el archivo no abierto, vamos a solicitar al usuario una diferente. El lector de archivos no debe ser capaz de pedir a los usuarios o tomar cualquier otra acción en respuesta. Su único propósito es la lectura de los archivos.
    • usted dijo: «Usted quiere que su bloque Finally para al menos intentar limpiar antes de salir.» Prueba para limpiar los sonidos un poco de miedo… ¿y si el bloque Finally se produce una excepción? (Hay un Try…Catch…Finally en su interior, no?)

  2. 59

    «Por fin» es una declaración de «Algo que siempre se debe hacer para asegurarse de que el estado del programa es sano». Como tal, es siempre una buena forma de tener uno, si hay alguna posibilidad de que las excepciones pueden sacudirse el estado del programa. El compilador también realiza un gran esfuerzo para asegurarse de que su por último código se ejecuta.

    «Pega» es una declaración de «me puede recuperarse de esta excepción». Sólo debe recuperarse de excepciones que usted realmente puede corregir la captura sin argumentos, dice «Hey, puedo recuperar de cualquier cosa!», que es casi siempre falso.

    Si fuera posible recuperarse de cada excepción, entonces sería realmente una semántica de sutileza, sobre lo que estamos declarando su intención de ser. Sin embargo, no lo es, y casi ciertamente fotogramas por encima de la suya, estarán mejor equipados para manejar ciertas excepciones. Como tal, el uso, finalmente, obtener su código de limpieza ejecutar de forma gratuita, pero aún vamos más conocimientos de los manipuladores de lidiar con el problema.

    • Su sentimiento es generalizado, pero lamentablemente ignora otro caso importante: expresamente invalidar un objeto cuya invariantes no puede sostener. Un patrón común es el código para adquirir un bloqueo, hacer algunos cambios a un objeto, y liberar el bloqueo. Si se produce una excepción después de hacer algunos, pero no todos los cambios, el objeto puede quedar en un estado no válido. Aunque en mi humilde opinión las mejores alternativas debe existen, que yo sepa no hay mejor método que captura cualquier excepción que se produce mientras el estado del objeto puede no ser válida, expresamente invalidar el estado, y rethrow.
  3. 32

    Porque cuando una sola línea, se produce una excepción, que no saben.

    Con el primer bloque de código, la excepción será simplemente absorbido, el programa seguirá ejecutándose incluso cuando el estado de que el programa podría estar equivocado.

    Con el segundo bloque, la excepción será lanzado y las burbujas de pero la reader.Close() todavía está garantizado a ejecutar.

    Si una excepción no es el esperado, entonces no hay que poner un bloque try..catch de la misma manera, será difícil de depuración más tarde, cuando el programa entró en mal estado y no tiene idea de por qué.

  4. 21

    Finalmente se ejecuta no importa qué. Por lo tanto, si su bloque try fue un éxito, que se ejecutará, si el bloque try falla, se ejecutará el bloque catch, y, a continuación, el bloque finally.

    También, es mejor tratar de usar la siguiente construcción:

    using (StreamReader reader=new  StreamReader("myfile.txt"))
    {
    }

    Como el uso de la declaración se ajusta automáticamente en un try /finally, y la corriente será cerrado automáticamente. (Usted tendrá que poner un try /catch en torno a la instrucción de uso si desea capturar la excepción).

    • Esto no es correcto. El uso de no ajustar el código con try/catch, debe decir try/finally
  5. 8

    Mientras que los 2 siguientes bloques de código son equivalentes, no son iguales.

    try
    {
      int i = 1/0; 
    }
    catch
    {
      reader.Close();
      throw;
    }
    
    try
    {
      int i = 1/0;
    }
    finally
    {
      reader.Close();
    }
    1. ‘por fin’ es la intención que revela el código. Se declara al compilador y a otros programadores que este código debe ejecutarse no importa qué.
    2. si tiene varios bloques catch y tiene el código de limpieza, usted necesita finalmente. Sin finalmente, se estaría duplicando su código de limpieza en cada bloque catch. (Principio SECO)

    finalmente bloques son especiales. El CLR reconoce y trata de código dentro de un bloque finally por separado de los bloques catch, y el CLR realiza un gran esfuerzo para garantizar que un bloque finally siempre se ejecuta. No es sólo azúcar sintáctico del compilador.

  6. 5

    Estoy de acuerdo con lo que parece ser el consenso aquí – un vacío «coger» es mala porque las máscaras de cualquier excepción que podría haber ocurrido en el bloque try.

    También, desde un punto de vista de la legibilidad, cuando veo a una ‘prueba’ bloque supongo que habrá un correspondiente «atrapar» declaración. Si sólo está utilizando una ‘prueba’ con el fin de garantizar que los recursos de que se asignen en el ‘finalmente’ bloque, usted podría considerar la «mediante» declaración de lugar:

    using (StreamReader reader = new StreamReader('myfile.txt'))
    {
        //do stuff here
    } //reader.dispose() is called automatically

    Puede utilizar el «uso de’ declaración con cualquier objeto que implementa IDisposable. El objeto del método dispose() se llama automáticamente al final de la cuadra.

  7. 3

    El try..por último bloque todavía lanzan las excepciones que se plantean. Todos finally hace es asegurarse de que el código de limpieza se ejecuta antes de que se produce la excepción.

    El try..catch con un vacío de captura por completo a consumir cualquier tipo de excepción y ocultar el hecho de que sucedió. El lector estará cerrado, pero no se sabe si la cosa correcta que pasó. ¿Y si su intención era escribir me para el archivo? En este caso, usted no lo va a hacer a esa parte del código y myfile.txt estará vacía. Hacer todo de la de aguas abajo de los métodos de manejar esto correctamente? Cuando vea el archivo vacío, va a ser capaz de adivinar correctamente que es vacía, debido a que se produce una excepción? Mejor lanzar la excepción y que se sepa que usted está haciendo algo mal.

    Otra razón es el try..catch hecho como esto es completamente incorrecto. Lo que usted está diciendo, haciendo esto es, «No importa lo que pase, yo puedo manejar esto.» ¿Qué acerca de StackOverflowException, se puede limpiar después de eso? ¿Qué acerca de OutOfMemoryException? En general, usted debe sólo controlar las excepciones que usted espera y sabe cómo manejar.

  8. 3

    Uso Try..Catch..Finally, si su método sabe cómo manejar la excepción localmente. La Excepción se produce en el Intento, Manejado en la Captura y después de esa limpieza se realiza en Finalmente.

    En caso de que su método no saben cómo manejar la excepción, sino que necesita una limpieza una vez que ha ocurrido utilizar Try..Finally

    Por esta excepción se propaga al llamar a los métodos y manejada si hay alguna adecuado Catch en la llamada a métodos.Si no hay controladores de excepción en el método actual o de cualquiera de los métodos de llamada, a continuación, la aplicación se bloquea.

    Por Try..Finally se asegura que el local que la limpieza es realizada antes de la propagación de la excepción a los métodos de llamadas.

    • Tan básico como la respuesta a esto es, es absolutamente el mejor. Es bueno estar en el hábito de try/catch/finally, incluso si uno de los dos últimos, se deja vacío. Hay MUY RARAS circunstancias en las que un bloque catch puede existir y estar vacía, pero al menos si escribes siempre try/catch/finally, usted verá el bloque vacío como usted está hojeando el código. Tener un vacío por último bloque es útil, de la misma manera. Si usted necesita la limpieza posterior, o la necesidad de depurar un estado en el momento de la excepción, es increíblemente útil.
  9. 2

    Si usted no sabe qué tipo de excepción para coger o qué hacer con él, no hay ningún punto en tener una instrucción catch. Usted debe dejarlo por un superior a quien llama que puede tener más información acerca de la situación para saber qué hacer.

    Usted todavía puede tener finalmente un comunicado en su lugar en caso de que haya una excepción, así que usted puede limpiar los recursos antes de que la excepción es lanzada a la persona que llama.

  10. 2

    Desde una perspectiva de legibilidad, es más explícitamente contar a las futuras código de lectores «esto de aquí es importante, se debe hacer sin importar lo que suceda.» Esta es la buena.

    También, vacío instrucciones catch tienden a tener un cierto «olfato» para ellos. Que podría ser un signo de que los desarrolladores no están pensando a través de las distintas excepciones que pueden ocurrir y cómo manejarlos.

  11. 2

    Por último es opcional-no hay ninguna razón para tener un bloque «Finally» si no hay recursos para limpiar.

    • Ahora QUE es un Cubo de Rubik que puedo resolver.
  12. 2

    Tomado de: aquí

    Sensibilización y captura de excepciones no debe habitualmente se presentan como parte de la ejecución correcta de un método. Cuando el desarrollo de las bibliotecas de clase, el código de cliente se le debe dar la oportunidad de probar para una condición de error antes de emprender una operación que puede resultar en una excepción que se plantea. Por ejemplo, el Sistema de.IO.FileStream proporciona un CanRead propiedad que se puede comprobar antes de llamar al método de Lectura, prevenir una posible excepción planteada, como se ilustra en el siguiente fragmento de código:

    Dim str Como Corriente = GetStream()
    Si (str.CanRead), A Continuación,
    ‘código para leer la secuencia de
    Final Si

    La decisión de si se debe comprobar el estado de un objeto antes de la invocación de un método en particular que puede provocar una excepción depende del estado esperado del objeto. Si un objeto FileStream se crea utilizando una ruta de archivo que deben existir y un constructor que debe devolver un archivo en modo de lectura, la comprobación de la propiedad CanRead no es necesario; la incapacidad de leer el FileStream sería una violación a la espera de que el comportamiento del método de las llamadas realizadas, y una excepción debe ser elevado. En contraste, si un método está documentado como devolver un FileStream de referencia que puede o puede no ser legible, la comprobación de la propiedad CanRead antes de intentar leer los datos es recomendable.

    Para ilustrar el impacto en el rendimiento que el uso de una «ejecutar hasta que la excepción de» codificación técnica puede causar, el rendimiento de un molde, lo que arroja un InvalidCastException si la conversión falla, es comparado con el de C# como operador, que devuelve null si la conversión falla. El rendimiento de las dos técnicas es idéntico para el caso de que el reparto es válido (ver Prueba 8.05), pero para el caso de que el reparto no es válido, y utilizando un molde produce una excepción, el uso de un yeso es 600 veces más lento que usando el operador (ver Prueba de 8.06). El alto impacto en el rendimiento de la excepción-técnica de lanzamiento incluye el costo de la asignación, lanzar y atrapar la excepción y el costo de la posterior recolección de basura del objeto de excepción, lo que significa que el impacto instantáneo de lanzar una excepción no es tan alta. A medida que más se producen excepciones, frecuente recolección de basura se convierte en un problema, por lo que el impacto global del uso frecuente de una excepción – tirar la codificación de la técnica es similar a la Prueba de 8.05.

    • Scott-si el texto que he citado anteriormente está detrás de expertsexchange.com’s paywall, usted probablemente no debería post que aquí. Puedo estar equivocado en esto, pero yo apuesto a que no es una buena idea.
  13. 2

    Si vas a leer C# para programadores usted va a entender, que el bloque finally se diseño para optimizar una aplicación y prevenir la pérdida de memoria.

    El CLR no elimina por completo las fugas… pueden producirse pérdidas de memoria del programa, si inadvertidamente mantener referencias a objetos no deseados

    Por ejemplo cuando se abre un archivo o base de datos de la conexión, la máquina será asignar memoria para atender la transacción, y que la memoria se mantiene no, a menos que la desecha o cerca de comando fue ejecutado. pero si durante la transacción, un error ha ocurrido, el procedimiento de comandos será terminado a no ser que estaba dentro de la try.. finally.. bloque.

    catch era diferente de finally en el sentido de que la captura se diseño para dar forma a manejar/administrar o interpretar el error en sí. Piense en ello como la persona que le dice «hola, he cogido algunos chicos malos, ¿qué quieres hacer con ellos?».
    mientras finally fue diseñado para asegurarse de que sus recursos fue colocada correctamente. Pensar que es de alguien que si existe o no algunos de los chicos malos de él se asegurará de que su propiedad estaba a salvo.

    Y deben permitir que los dos trabajen juntos para el bien.

    por ejemplo:

    try
    {
      StreamReader reader=new  StreamReader("myfile.txt");
      //do other stuff
    }
    catch(Exception ex){
     //Create log, or show notification
     generic.Createlog("Error", ex.message);
    }
    finally   //Will execute despite any exception
    {
      reader.Close();
    }
  14. 1

    Con por último, usted puede limpiar los recursos, incluso si su instrucción catch lanza la excepción hasta el programa de llamada. Con su ejemplo que contiene el vacío de la instrucción catch, hay poca diferencia. Sin embargo, si en su captura, que algunos de procesamiento y tiro el error, o incluso ni siquiera tienen coger a todos, el que finalmente obtendrá ejecutar.

  15. 1

    Bueno para uno, es malo práctica para la captura de excepciones no molestar a manejar. Echa un vistazo Capítulo 5 acerca de .El Rendimiento Neto de Mejorar .NETO de Rendimiento de la Aplicación y la Escalabilidad. Nota de lado, probablemente debería ser la carga de la corriente dentro del bloque try, de esa manera, usted puede coger el pertinente excepción si se produce un error. La creación de la secuencia de fuera del bloque try derrotas de su propósito.

  16. 0

    Entre probablemente muchas razones, las excepciones son muy lentos para ejecutar. Usted fácilmente puede paralizar su ejecución veces si esto sucede mucho.

  17. 0

    El problema con los bloques try/catch que capturar todas las excepciones es que su programa está ahora en un estado indeterminado si un desconocido excepción se produce. Esto va completamente en contra de la falla rápido regla – usted no quiere que su programa a seguir si se produce una excepción. El de arriba try/catch incluso coger OutOfMemoryExceptions, pero que definitivamente es un estado en el que su programa no se ejecuta en.

    Bloques Try/finally permitir la ejecución de código de limpieza, mientras que todavía no rápido. Para la mayoría de las circunstancias, usted sólo desea capturar todas las excepciones a nivel mundial, por lo que usted puede acceder a ellos, y luego salir.

  18. 0

    La diferencia entre sus ejemplos es insignificante ya que no se producen excepciones.

    Sin embargo, si se produce una excepción, mientras que en la ‘prueba’ de la cláusula, el primer ejemplo se trague por completo. El segundo ejemplo, se plantean la excepción para el siguiente paso en la pila de llamadas, por lo que la diferencia en los ejemplos establecidos es que uno oculta excepciones (primer ejemplo), y el otro (segundo ejemplo) conserva la información de la excepción para el potencial de manipulación mientras se sigue ejecutando el contenido de la ‘finalmente’ cláusula.

    Si, por ejemplo, fueron a poner el código en la ‘trampa’ de la cláusula de la primer ejemplo que lanzó una excepción (la que fue inicialmente planteado, o uno nuevo), el lector de código de limpieza nunca iba a ejecutar. Finalmente ejecuta independientemente de lo que sucede en la ‘trampa’ de la cláusula.

    Así, la principal diferencia entre la ‘captura’ y ‘por fin’ es que el contenido de la ‘finalmente’ bloque (con raras excepciones) puede ser considerado garantizado a ejecutar, incluso en la cara de una excepción inesperada, mientras que cualquier código que sigue a una ‘captura’ de la cláusula (pero fuera de un «por fin» cláusula de no realizar dicha garantía.

    Por cierto, Arroyo y StreamReader implementar IDisposable, y puede ser envuelto en un ‘uso’ del bloque. «Uso de’ bloques son el equivalente semántico de try/finally (no «coger»), por lo que su ejemplo podría ser más lacónicamente se expresa como:

    using (StreamReader reader = new  StreamReader("myfile.txt"))
    {
      int i = 5 / 0;
    }

    …que va a cerrar y disponer de la StreamReader ejemplo, cuando se sale del ámbito.
    Espero que esto ayude.

  19. 0

    try {…} catch{} no es siempre malo. No es un patrón común, pero tiendo a uso cuando necesito para el apagado de los recursos, no importa qué, como el cierre de una (posiblemente) sockets abiertos en el extremo de un hilo.

Dejar respuesta

Please enter your comment!
Please enter your name here