¿Por qué utilizar Finalmente en Try … Catch

Veo que la Finally en Try .. Catch siempre se ejecuta después de alguna de las partes de la ejecución del bloque try catch.

Es diferente a omita la Finally sección y sólo se ejecuta después de que, fuera del bloque try catch?

Ejemplo 1, Try … Catch … Finally … End Try

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    Finally
        'Do cleanup
    End Try

Ejemplo 2, Try … Catch … End Try … Hacer la finalmente las cosas fuera

    Try
        'Do something
    Catch ex As Exception
        'Handle exception
    End Try
    'Do cleanup
  • Seguro que no la quiero coger a mi ex de hacer nada.
InformationsquelleAutor awe | 2009-07-21

14 Kommentare

  1. 66

    Sí, es diferente. Finalmente se ejecutará siempre (salvo caída del programa). Si sale de la función dentro del bloque try catch, o de otro error se produce en el intento o la captura, la que finalmente va a ejecutar. Usted no conseguirá que la funcionalidad no está utilizando la instrucción finally.

    • Por desgracia finally bloques que por defecto si el programa se bloquea en diversas formas. Pero puede omitir este paso si desea: manejar AppDomain.UnhandledException llamar Environment.FailFast.
    • Aunque si eres un programador de Java, estás de suerte: las excepciones no controladas ejecutar finally bloques y no hay nada que usted puede hacer sobre él.
    • Bueno, usted puede hacer algo al respecto, puede diseñar/escribir su código, así que no usar Excepciones para el control de flujo y de no utilizar el bloque finally para cosas similares. Finalmente debe ser utilizado para la limpieza, que siempre debe ocurrir.
    • No es cierto, hay momentos en que, finalmente, no puede ser llamado. Como abortar el programa desde el sistema operativo, o el equipo de estrellarse.
    • Las dos maneras, no se ejecutará cuando el subproceso que ejecuta el try/catch detiene la ejecución o la JVM está terminado. De modo que el hilo se puede detener y el resto del programa sigue y nunca se sabe (salvo buen registros de codificación/) si funcionó o no.
  2. 12

    Código con cuatro botones de radio:

    • Retorno en INTENTAR
    • De retorno en la CAPTURA
    • Tiro en la CAPTURA
    • Finalizar la CAPTURA

      private void checkFinally()
      {
          try
          {
              doFinally();
          }
          catch
          {
              Console.WriteLine(" Breaking news: a crash occured. ");
          }
      }
      
      private void doFinally()
      {
          Console.WriteLine(" ");
          Console.Write("Here goes: " 
              + (radioReturnInTry.Checked ? "2. Return in try: " 
                      : (radioReturnInCatch.Checked? "3. Retrun in catch: "
                          : (radioThrowInCatch.Checked? "4. Throw in catch: "
                              : "1. Continue in catch: "))) );
          try
          {
              if (radioReturnInTry.Checked)
              {
                  Console.Write(" Returning in try. ");
                  return;
              }
              Console.Write(" Throwing up in try.  ");
              throw new Exception("check your checkbox.");
          }
          catch (Exception ex)
          {
              Console.Write(" ...caughtcha! ");
              if (radioReturnInCatch.Checked)
              {
                  Console.Write("Returning in catch. ");
                  return;
              }
              if (radioThrowInCatch.Checked)
              {
                  Console.Write(" Throwing up in catch. ");
                  throw new Exception("after caught");
              }
          }
          finally { Console.Write(" Finally!!"); }
          Console.WriteLine(" Done!!!"); // before adding checkboxThrowInCatch, 
          // this would never happen (and was marked grey by ReSharper)
      
      }

    De salida:

    • Aquí va: 1. Continuar en la captura: Tirar para arriba en el intento. …caughtcha! Por fin!! Hecho!!!
    • Aquí va: 2. De regreso en probar: Volver en el intento. Por fin!!
    • Aquí va: 3. Retrun en la captura: Tirar para arriba en el intento. …caughtcha! Regresando en la captura. Por fin!!
    • Aquí va: 4. Tiro en la captura: Tirar para arriba en el intento. …caughtcha! Vomitando en la captura. Por fin!! Noticias de última hora: un accidente ocurrido.

    A resumir:
    Finalmente se tiene el cuidado de dos cosas:

    1. De código que devuelto en la prueba o en la captura.
    2. O Si había una excepción en el intento, Y LANZAR una excepción en la captura,
    3. o, si había una excepción en el intento, Y NO COGER esa excepción,

    Finalmente, para resumir «FINALMENTE»: Finalmente no hace nada especial si usted ha intentado,y

    1. NO RETORNO,
    2. y atrapado en las excepciones durante el juicio, y, a continuación,
    3. NO RETORNO en el entendido bien, y
    4. NO TIRAR o tener código que lanza.

    Y por último pero no menos importante (por fin):
    Si usted tiene una excepción en el código que NO cuajó, el código de la mosca, SIN LLEGAR a LA FINAL.

    La esperanza de que esto está claro. (Ahora es a mí…)

    Moshe

  3. 7

    Finalmente contiene el código que debe ser evaluado en todas las condiciones [de si o no se ha producido una excepción].

    No hay manera de salir de un bloque try sin la ejecución de su bloque finally. Si el bloque finally existe, siempre se ejecuta. (Esta declaración es verdadera para todos los intentos y propósitos. Hay una manera de salir de un bloque try sin ejecutar el bloque finally. Si el código se ejecuta en un Sistema.exit(0); desde dentro de un bloque try, se termina la aplicación sin la finalmente la ejecución. Por otro lado, si se desenchufa la máquina durante un bloque try, el que finalmente no se ejecute.)

    El principal uso es para la eliminación de objetos. Será útil cuando se desea cerrar de usuario
    los recursos definidos como archivo , abrió los recursos(db stmts).

    Editar

    También, finalmente, no se ejecuta después de que un stackoverflow excepción.

    • Será el bloque finally se ejecuta si hay un StackOverflowException?
    • No, No va a ser ejecutado.
    • Esto supone que el proceso no finaliza abruptamente.
    • Gracias. Editado mi post.
  4. 5

    La diferencia es que cuando el código de la try bloque lanza una excepción que no es capturado por la catch bloque.

    Normalmente un catch bloque de la captura de un tipo específico de excepción, y permita que nada a través de. En ese caso, el finally bloque va a ejecutar.

    La finally bloque también se ejecuta si el código en el try bloque returns.

    • +1: buen punto, con excepción no capturada tipos
    • no importa si el que se captura la excepción o no. El bloque finally siempre se ejecuta (baring condiciones excepcionales tales como «fuerza bruta» de la aplicación de las salidas)
    • FS: Sí, pero si la excepción se detecta, que no hay diferencia entre el asombro de dos ejemplos (de restricción de otras excepciones planteadas, return declaraciones, etc.). Si no es capturado, no es una diferencia. Eso es lo que asombro estaba preguntando acerca de.
  5. 3

    Esta es una buena idea cuando se trata con conexiones de base de datos o en cualquier momento que los objetos necesitan ser eliminados. En caso de que algo va mal, mientras que la ejecución de consultas, usted todavía puede cerrar la conexión de forma segura. También ayuda a limpiar el código que el bloque fuera del try/catch/finally bloque no es capaz de acceder.

  6. 2

    El bloque Finally se ejecutará independientemente de si sale de la función debido a una excepción. (hay algunas excepciones a esta regla, ver a esta pregunta de stackoverflow para obtener más información).

    Por ejemplo:

    Try
        'Do something
    Catch ex As Exception
        if 'Some Condition
           throw ex
        else
           'Handle exception
    Finally
        'Do cleanup
    End Try

    En este caso, el bloque Finally todavía ser ejecutadas, incluso a pesar de que usted puede lanzar una excepción de la función.

    Esta es una buena práctica a seguir porque se asegura de que su código de limpieza siempre se ejecuta. Por supuesto, el uso de la Resoource Adquisición De Inicialización lenguaje es mucho más limpio manera de asegurar que los recursos lleguen limpiado, pero no estoy lo suficientemente versado en VB.net para saber si esto es posible de hacer.

    • «siempre»? Hay un número de razones por las que un bloque finally, no se ejecutan.
    • tenga en cuenta que el bloque finally no es guarateed para que se ejecute siempre, hay algunas excepciones (!) a esta regla; StackOverflowException ser uno de ellos.
    • Desconectar el equipo, mientras que en el medio del bloque try también hará que finalmente no se va a ejecutar 🙂
    • Oy, perdona mi ignorancia de la CLR. He editado mi post.
    • Si la ejecución alcanza un alcance externo, todos los interiores de bloques finally se garantiza que han sido «ejecutar» [aunque algunos hayan salido antes debido a las excepciones]. Tenga en cuenta que es posible en vb.net o CIL para un exterior try bloque de incluir código que se ejecuta desde dentro del contexto de un anidada por último bloque, a pesar de que C# no exponer la funcionalidad. Como para RAII, vb.net y C# puede aplicar el concepto a las variables locales a través de la using construir, pero útil no pueden aplicar a los campos.
    • Que realmente debería agregar un PlugPulled excepción. Y un NotPluggedIn excepción, solo para atender todas las eventualidades. El StackOverflow excepción debería redirigir a este sitio, por supuesto.

  7. 2

    Finalmente debe ser utilizado para todo lo que se necesita hacer en el fin de mantener un sistema coherente. Esto generalmente significa que la liberación de recursos

    Finalmente se ejecuta siempre, no importa lo que se produjo una excepción. Debe ser utilizado para la liberación de los recursos, en los siguientes casos:

    • Finalizar una conexión
    • Cerrar un archivo de controlador de
    • Memoria libre
    • Cerrar una conexión de base de datos

    Permítanme darles un ejemplo completo. Imagínese que usted está enviando mensajes a través de la red. En pseudo-có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 tiene en la try bloque genera una excepción que no es NetworkError, por ejemplo, MethodNotFound. En el primer caso, el método finalizes_connection() serán llamados, y en el segundo, no.

    Una conexión es, naturalmente, se realiza a través de más de un programa. Entonces, ¿qué sucede en el caso de un MethodNotFound excepción para el otro programa? En el primer caso, el programa va a terminar la conexión y el otro programa y será feliz. En el segundo caso, el otro programa se puede espera de su respuesta para siempre. ¿Qué tal si el programa sólo se puede recibir una conexión por tiempo? Usted acaba de fastidiaron el otro programa así.

    Esto también se aplica para un archivo, por ejemplo, que se abrió y otros programas no ser capaz de abrir para lectura (en Windows). Y para la memoria, nunca es liberado y ahora usted tiene una pérdida de memoria.

    • Si sólo coger un específico tipo de excepción, esto es obvio, pero en mi ejemplo yo captura excepción de tipo Exception que es realmente una excepción de alguna tipo. A continuación, la necesidad de finally no es evidente, pero esto es bien contestadas por otros.
  8. 1

    utilizar finalmente, para la limpieza de código, por ejemplo db conexiones o archivos que estén abiertos que debe estar cerca. Prácticamente cualquier código de limpieza que necesita para ejecutar regardsless de una excepción o no

    también, su manejo de excepciones puede requerir volver a lanzar la excepción, o otra excepción, en cuyo caso el código después de que el bloque no será ejecutado

  9. 1

    Haciendo limpieza en un bloque finally para asegurarse de que se ejecuta. Si el bloque catch no lidiar con la excepción (es decir. simplemente registra), o incluso hace que otra excepción, el código en el bloque finally se ejecutará.

  10. 1

    En la parte superior de lo que todos decían, semánticamente creo que son diferentes.

    Código en el bloque finally se establece claramente que usted está haciendo finalización tipo de tareas para el contenido dentro del try-catch. Creo que esto hace que sea más clara la lectura.

    • Estoy totalmente de acuerdo con usted en esto. Yo era solo por curiosidad, si se tratara de cualquier tipo de diferencia, y con base en lo que otros han dicho, es…
  11. 1

    Tan lejos como puedo recordar, nunca he usado un try/catch/finally bloque en mi .NET de código.

    En general, captura de excepciones en el nivel medio, rara vez es necesaria. Excepciones generalmente se propagan a un nivel superior de controlador en el nivel de presentación (y posiblemente capturado y reenviada a un nivel límite de lo que pueden grabarse).

    Así que en el nivel medio, lo más a menudo a ver try/finally (o el «uso de la» declaración») para que los recursos que se limpian. Y en try/catch en la parte superior controlador de nivel en el nivel de presentación.

    En los raros casos en que necesito tanto de atrapar una excepción y hacer algo de limpieza, yo prefiero refactorizar para que la siguiente:

    try
    {
        ... do something
    }
    catch
    {
       ... handle exception
    }
    finally
    {
       ... cleanup
    }

    se convierte en:

    try
    {
        DoSomethingAndCleanup();
    }
    catch
    {
       ... handle exception
    }
    
    ...
    private void DoSomethingAndCleanup()
    {
        try
        {
            ... do something
        }
        finally
        {
            ... cleanup
        }
    }

    Mi humilde opinión, este es mucho más limpio.

    • Cathcing excepciones en el nivel medio, tendría sentido si el original excepcion es causado por algo que tiene sentido en el código interno, pero no en el nivel de presentación. Entonces es de sentido para lanzar una excepción que da más detalles sobre el contexto para lo que realmente salió mal.
    • Es una lástima que no hay idiomáticas manera de hacer algo en respuesta a una excepción sin un pretexto de resolverlo. Es muy común que los métodos para poner temporalmente a un objeto en un estado corrupto, pero luego solucionarlo antes de que vuelvan. Dicho código debe ser vigilado por un try bloque que expresamente invalidar el objeto si se produce una excepción inesperada; parece repulsivo para catch una excepción no tiene ninguna expectativa de resolver, pero no estoy seguro de qué alternativa existe en C#.
  12. 0

    Captura no ejecutar después de alguna de las partes de la ejecución del bloque try catch. Captura sólo se ejecuta si se produce una excepción y el bloque catch se puede manejar ese tipo de excepción.

    El bloque finally es el que se ejecutará cuando el bloque try se completa. Por completo, quiero decir que se termina normalmente, o se sale en alguna manera (sale de un bucle, se devuelve desde el método lanza una excepción, etc.)

    Si pones el código fuera del bloque finally y se produce una excepción (por ejemplo), a continuación, el código no se ejecutará si la excepción no se detecta, o se vuelve a producir en el bloque catch, o una nueva excepción se produce en el bloque catch. Si la pones en el interior del bloque finally, a continuación, será ejecutado.

    Básicamente, la limpieza debe ser puesto en el bloque finally.

  13. 0

    Después de leer la respuesta a mi comentario anterior me puse a pensar en algunas cosas.

    La pregunta, básicamente, se puede no se puede responder completamente sin necesidad de conocer el código en cuestión.

    La razón es que no todo el código se puede colocar en un bloque finally. E. g. el rendimiento de las declaraciones de no permitir que en el último (y captura) de los bloques. El bloque try puede tener varias ejecución de las ramas donde algunas devoluciones y otros no. El que finalmente se ejecuta en todos los casos, mientras que en el ejemplo sin fin, que no sería el caso para la limpieza del código. Es más, usted no puede saltar (goto) en un bloque finally aunque es muy raro que usted puede saltar el código después de que el bloque catch. No se puede volver de un bloque finally bien.

    Hay muy pocos aunque muy poco frecuente, la mayoría de los casos en los que la respuesta depende del código real.

  14. 0

    Lo utilizo a menudo es (I encapsulado que en un aspecto, pero esto es lo que se deriva el aspecto de):

    public static DoLengthyProcessing(this Control control, Action<Control> action)
    {
        Cursor oldCursor = control.Cursor
        try
        {
            control.Cursor = Cursors.WaitCursor;
            action(control);
        }
        catch (Exception ex)
        {
            ErrorHandler.Current.Handler(ex);
        }
        finally
        {
            control.Cursor = oldCursor;
        }
    }

    O, el uso de AOP (como yo).

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea