27
First I would like to know why in using the finally
What are its advantages? It really only serves for when an exit occurs from within the scope of a block try-catch
, as when some return
or goto
inside?
27
First I would like to know why in using the finally
What are its advantages? It really only serves for when an exit occurs from within the scope of a block try-catch
, as when some return
or goto
inside?
23
Other answers have already answered the most important question. Complementing, the most common use for the finally
is the cleaning of resources.
When you use a variable declaration with using
is actually using a try-finally
So when does:
using (Font font1 = new Font("Arial", 10.0f)) {
byte charset = font1.GdiCharSet;
}
Is the same as:
{
Font font1 = new Font("Arial", 10.0f);
try {
byte charset = font1.GdiCharSet;
}
finally {
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
In fact it’s just syntax sugar. The compiler actually changes the using
by the second construction.
The catch
is used to capture exceptions and only, the finally
is executed at all times after the end of a code block within the try
or catch
, if there is one, with or without exception. The finally
will be executed anyway, even if before he has a return
or goto
trying to avoid it. It is not possible to exit the code block started by try
without going through the finally
(at least not under normal C#conditions, as well recalled by Omni, there are catastrophic situations that CLR may not guarantee the execution of finally
, in addition, in theory it is possible to change the IL to avoid it, but this is something wrong to do).
There’s no way to use one return
or goto
within a finally
. Or you use in the try
or in the catch
or place it after the finally
. Remembering that if you’re after the block finally
, it may not be executed, as well demonstrated by the last code of Lucas Nunes' reply.
I found this excellent response (see also the answer from Jon Skeet) showing how the return
in the block protected by try
. This code:
static int Test() {
try {
return SomeNumber();
} finally {
Foo();
}
}
Compile for the CIL:
.method private hidebysig static int32 Test() cil managed
{
.maxstack 1
.locals init (
[0] int32 CS$1$0000)
L_0000: call int32 Program::SomeNumber()
L_0005: stloc.0
L_0006: leave.s L_000e
L_0008: call void Program::Foo()
L_000d: endfinally
L_000e: ldloc.0
L_000f: ret
.try L_0000 to L_0008 finally handler L_0008 to L_000e
}
That would be the same as:
private static int Test()
{
int CS$1$0000;
try
{
CS$1$0000 = SomeNumber();
}
finally
{
Foo();
}
return CS$1$0000;
}
The return
is executed at the end, but the expression contained in it runs where the return
in the original code.
+1 by reference to non-normal exit conditions.
15
You must use finally
to finalize/release resources you may have used in a try
, even if an exception is made, the code in the finally
will be executed.
The operation is basically this:
try
{
// seu código
}
catch
{
// exceção
}
finally
{
// sempre faz isso
}
For example:
Suppose you open a file on try
, but there is an exception. In finally
is the right place for you to close the file.
String path = @"arquivo_qualquer.dat";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Erro de leitura em: {0}. Mensagem = {1}", path, e.Message);
}
finally
{
if (file != null)
{
file.Close();
}
}
Note that the above code is different from:
String path = @"arquivo_qualquer.dat";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Erro de leitura em: {0}. Mensagem = {1}", path, e.Message);
}
if (file != null)
{
file.Close();
}
In this second case there is no guarantee that file
will be closed, while in the first there is.
The example below illustrates this, where the return
in the catch
prevents the last lines of the programme from being executed, but finally
evening.
static void Main(string[] args)
{
string str = "1000";
Object obj = str;
int numero = 0;
try
{
// Essa conversão falhará.
numero = (int)obj;
Console.WriteLine("Essa linha não será executada.");
}
catch (System.Exception e)
{
Console.WriteLine("A conversão falhou.");
// Esse return fará com que o último WriteLine não seja executado.
return;
}
finally
{
Console.WriteLine("Essa linha sempre será executada.");
}
Console.WriteLine("Aparentemente essa linha seria executada.");
}
7
The finally
only serves for use together with a try/catch
.
Its use is indicated for a block situation try
where, if successful or failed, the code will always be executed. This is useful for object relocation, log audit of some information, or some code that is essential for execution.
Just like the catch
, the block finally
is optional.
It is not necessary to use it to return some value. It can be used, but is not required.
Use:
try
{
/* Aqui fica o código propenso a algum erro */
}
catch (Exception ex)
{
/* Aqui é executado quando alguma exceção acontece */
}
finally
{
/* Independente de ter caído ou não no catch, este trecho sempre executa */
}
Reference: http://msdn.microsoft.com/pt-br/library/zwc8s4fz.aspx
6
The code inside a block finally
will run regardless whether or not there is an exception. This is useful when it comes to certain functions in which you need to do closing connections, disconnect or release an object.
try
{
FazerAlgumaCoisa();
}
catch
{
CapturarAlgo();
}
finally
{
SempreFazerIsso();
}
You could be doing this:
try
{
FazerAlgumaCoisa();
}
catch
{
CapturarAlgo();
}
SempreFazerIsso();
In the last code, the call SempreFazerIsso()
will not be executed if the code within the instruction catch
issue a return or launch a new exception.
4
"Finally" is very useful when you open a database connection and, before closing it, decide to use a "Try catch()". You can close this same connection within Finally, so you ensure that the connection will be closed.
2
Another case where you can use Finally after Try/catch, is in the situation of manipulating files in the middle of your process and not to fill the code with File.Delete, you can just clear the folder in Finally or still save the paths and names in a variable and clear before leaving.
Other case? You can only use it after one try/catch
.
Kyllopardiun, what I meant, was to demonstrate a case of using Try/catch/Finally - in order to control errors and fire emails from Exception. Clearly, the Finally is after a Try/catch.
Browser other questions tagged c# .net exception try-finally
You are not signed in. Login or sign up in order to post.
A comment just to add the good answers that are already here. There are rare cases where Finally may not run, more properly in case of catastrophic system failures (power cut, out of memory). Keep this in mind and don’t assume that all code in Finally is guaranteed. (In a more playful tone) See this example (http://thedailywtf.com/Articles/My-Tales.aspx)
– Omni