Lo que está adentro finalmente los bloques se ejecutan (casi) siempre, entonces, ¿cuál es la diferencia entre encerrar el código en él o dejarlo sin cerrar?
Lo que está adentro finalmente los bloques se ejecutan (casi) siempre, entonces, ¿cuál es la diferencia entre encerrar el código en él o dejarlo sin cerrar?
Respuestas:
El código dentro de un bloque finalmente se ejecutará independientemente de si hay una excepción o no. Esto es muy útil cuando se trata de ciertas funciones de limpieza que debe ejecutar siempre como cerrar las conexiones.
Ahora, estoy adivinando su pregunta es por qué usted debe hacer esto:
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
Cuando puedes hacer esto:
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
La respuesta es que muchas veces el código dentro de su declaración catch volverá a lanzar una excepción o saldrá de la función actual. Con el último código, el "alwaysDoThis ();" La llamada no se ejecutará si el código dentro de la instrucción catch emite una devolución o arroja una nueva excepción.
La mayoría de las ventajas de usar try-finally ya se han señalado, pero pensé en agregar esta:
try
{
// Code here that might throw an exception...
if (arbitraryCondition)
{
return true;
}
// Code here that might throw an exception...
}
finally
{
// Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}
Este comportamiento lo hace muy útil en diversas situaciones, particularmente cuando necesita realizar una limpieza (desechar recursos), aunque un bloque de uso suele ser mejor en este caso.
cada vez que use solicitudes de código no administradas como lectores de flujo, solicitudes de db, etc. y desea detectar la excepción, luego use try catch finalmente y cierre la secuencia, el lector de datos, etc., finalmente, si no lo hace cuando se produce un error, la conexión no se cierra, esto es realmente malo con las solicitudes de db
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
si no desea detectar el error, use
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
y el objeto de conexión se eliminará automáticamente si hay un error, pero no captura el error
Porque finalmente se ejecutará incluso si no manejas una excepción en un bloque catch.
Finalmente, las declaraciones pueden ejecutarse incluso después del retorno.
private int myfun()
{
int a = 100; //any number
int b = 0;
try
{
a = (5 / b);
return a;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return a;
}
// Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected"
finally
{
Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above
}
Response.Write("Statement after return after finally"); // -->Unreachable code
}
finally
, como en:
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
es una oportunidad garantizada para ejecutar código después de su try..catch
bloqueo, independientemente de si su bloque try produjo o no una excepción.
Eso lo hace perfecto para cosas como liberar recursos, conexiones db, identificadores de archivos, etc.
Explicaré el uso de finalmente con una excepción de lector de archivos Ejemplo
try{ StreamReader strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); StreamReader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); }
en el ejemplo anterior, si falta el archivo llamado Data.txt, se generará una excepción y se manejará, pero la declaración llamada StreamReader.Close();
nunca se ejecutará.
Debido a esto, los recursos asociados con el lector nunca se lanzaron.
StreamReader strReader = null; try{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); } catch (Exception ex){ Console.WriteLine(ex.Message); } finally{ if (strReader != null){ StreamReader.Close(); } }
Happy Coding :)
Nota: "@" se utiliza para crear una cadena literal , para evitar el error de "Secuencia de escape no reconocida". El símbolo @ significa leer esa cadena literalmente, y no interpretar los caracteres de control de otra manera.
Supongamos que necesita volver a colocar el cursor en el puntero predeterminado en lugar de un cursor en espera (reloj de arena). Si se lanza una excepción antes de configurar el cursor, y la aplicación no se bloquea por completo, podría quedar con un cursor confuso.
A veces no desea manejar una excepción (sin bloqueo), pero desea ejecutar un código de limpieza.
Por ejemplo:
try
{
// exception (or not)
}
finally
{
// clean up always
}
El último bloque es valioso para limpiar los recursos asignados en el bloque de prueba, así como para ejecutar cualquier código que deba ejecutarse incluso si hay una excepción. El control siempre se pasa al bloque finalmente, independientemente de cómo salga el bloque try.
Ahh ... creo que veo lo que estás diciendo! Me tomó un segundo ... te preguntas "por qué colocarlo en el bloque finalmente en lugar de después del bloque finalmente y completamente fuera del try-catch-finally".
Como ejemplo, podría deberse a que está deteniendo la ejecución si arroja un error, pero aún desea limpiar recursos, como archivos abiertos, conexiones de bases de datos, etc.
El flujo de control del bloque Finalmente es posterior al bloque Try o Catch.
[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]
con la excepción 1> 2> 3> 4> 5 si 3 tiene una declaración de devolución 1> 2> 3> 4
sin excepción 1> 2> 4> 5 si 2 tiene una declaración de retorno 1> 2> 4
Como se menciona en la documentación :
Un uso común de catch y finalmente juntos es obtener y usar recursos en un bloque try, lidiar con circunstancias excepcionales en un bloque catch y liberar los recursos en el bloque finalmente.
También vale la pena leer esto , que dice:
Una vez que se encuentra una cláusula catch coincidente, el sistema se prepara para transferir el control a la primera declaración de la cláusula catch. Antes de que comience la ejecución de la cláusula catch, el sistema primero ejecuta, en orden, cualquier cláusula finalmente asociada con las declaraciones try más anidadas que la que detectó la excepción.
Por lo tanto, está claro que el código que reside en una finally
cláusula se ejecutará incluso si una catch
cláusula anterior tenía una return
declaración.