O que quer que esteja dentro dos blocos finalmente é executado (quase) sempre, então qual é a diferença entre colocar o código nele ou deixá-lo não fechado?
O que quer que esteja dentro dos blocos finalmente é executado (quase) sempre, então qual é a diferença entre colocar o código nele ou deixá-lo não fechado?
Respostas:
The code inside a finally block will get executed regardless of whether or not there is an exception. This comes in very handy when it comes to certain housekeeping functions you need to always run like closing connections.
Now, I'm guessing your question is why you should do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
Quando você pode fazer isso:
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
A resposta é que, muitas vezes, o código dentro de sua instrução catch repetirá uma exceção ou interromperá a função atual. Com o último código, o "alwaysDoThis ();" chamada não será executada se o código contido na instrução catch emitir um retorno ou lançar uma nova exceção.
A maioria das vantagens do uso do try-finalmente já foi apontada, mas pensei em adicionar este:
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).
}
Esse comportamento o torna muito útil em várias situações, principalmente quando você precisa executar uma limpeza (dispor de recursos), embora um bloco de uso geralmente seja melhor nesse caso.
sempre que você usar solicitações de código não gerenciadas, como leitores de fluxo, solicitações de banco de dados, etc; e você deseja capturar a exceção, use try catch finalmente e feche o fluxo, leitor de dados, etc. finalmente, se não o fizer, quando ocorrer um erro, a conexão não será fechada.
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
se você não quiser pegar o erro, use
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
e o objeto de conexão será descartado automaticamente se houver um erro, mas você não captura o erro
Porque finalmente será executado mesmo que você não lide com uma exceção em um bloco de captura.
Finalmente, as instruções podem ser executadas mesmo após o 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 em:
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
is a guaranteed opportunity to execute code after your try..catch
block, regardless of whether or not your try block threw an exception.
That makes it perfect for things like releasing resources, db connections, file handles, etc.
eu vou explicar o uso de, finalmente, com uma exceção leitor de arquivos Exemplo
try{ StreamReader strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); StreamReader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); }
no exemplo acima, se o arquivo chamado Data.txt estiver ausente, uma exceção será lançada e será tratada, mas a instrução chamada StreamReader.Close();
nunca será executada.
Por esse motivo, os recursos associados ao leitor nunca foram liberados.
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: "@" é usado para criar uma sequência literal , para evitar o erro de "Sequência de escape não reconhecida". O símbolo @ significa ler essa string literalmente e não interpreta os caracteres de controle de outra maneira.
Digamos que você precise definir o cursor de volta ao ponteiro padrão em vez de um cursor em espera (ampulheta). Se uma exceção for lançada antes de definir o cursor e não travar completamente o aplicativo, você poderá ficar com um cursor confuso.
Às vezes, você não deseja manipular uma exceção (sem bloqueio de captura), mas deseja executar algum código de limpeza.
Por exemplo:
try
{
// exception (or not)
}
finally
{
// clean up always
}
O bloco final é valioso para limpar todos os recursos alocados no bloco try, além de executar qualquer código que deve ser executado mesmo se houver uma exceção. O controle sempre é passado para o bloco final, independentemente da saída do bloco try.
Ahh...I think I see what you're saying! Took me a sec...you're wondering "why place it in the finally block instead of after the finally block and completely outside the try-catch-finally".
As an example, it might be because you are halting execution if you throw an error, but you still want to clean up resources, such as open files, database connections, etc.
Control Flow of the Finally Block is either after the Try or Catch block.
[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]
with Exception 1 > 2 > 3 > 4 > 5 if 3 has a Return statement 1 > 2 > 3 > 4
without Exception 1 > 2 > 4 > 5 if 2 has a return statement 1 > 2 > 4
As mentioned in the documentation:
A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
It is also worth reading this, which states:
Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.
So it is clear that code which resides in a finally
clause will be executed even if a prior catch
clause had a return
statement.