33

The syntax will change from language to language, but this is a general question.

What is the difference between this....

try
{
     Console.WriteLine("Executing the try statement.");
     throw new NullReferenceException();
}
catch (NullReferenceException e)
{
     Console.WriteLine("{0} Caught exception #1.", e);
}       
finally
{
     Console.WriteLine("Executing finally block.");
}

and this....

try
{
    Console.WriteLine("Executing the try statement.");
    throw new NullReferenceException();
}
catch (NullReferenceException e)
{
    Console.WriteLine("{0} Caught exception #1.", e);
}        
Console.WriteLine("Executing finally block.");

I keep seeing it being used, so I assume there's a good reason to use finally, but I can't figure out how it's any different from just putting code after the statement since it will still run.

Is there ever a scenario where finally doesn't run?

cHao
  • 84,970
  • 20
  • 145
  • 172
Maxx
  • 3,925
  • 8
  • 33
  • 38
  • possible duplicate of [try catch finally question](http://stackoverflow.com/questions/3304308/try-catch-finally-question) – epascarello May 23 '13 at 02:36
  • 2
    ..which is a possible duplicate of http://stackoverflow.com/questions/3216046/does-the-c-sharp-finally-block-always-execute which is a possible duplicate of http://stackoverflow.com/questions/345091/will-code-in-a-finally-statement-fire-if-i-return-a-value-in-a-try-block, which has the best answer to this question. Well, a good, sweet & short one. – Mathieu Guindon May 23 '13 at 02:44

10 Answers10

42

In your example, it doesn't make a whole lot of difference.

Picture this, though:

    try
    {
        Console.WriteLine("Executing the try statement.");
        throw new NullReferenceException();
    }
    catch (SomeOtherException e)
    {
        Console.WriteLine("{0} Caught exception #1.", e);
    }       
    finally
    {
        Console.WriteLine("Executing finally block.");
    }

    Console.WriteLine("Executing stuff after try/catch/finally.");

In this case, the catch won't catch the error, so anything after the whole try/catch/finally will never be reached. However, the finally block will still run.

cHao
  • 84,970
  • 20
  • 145
  • 172
  • 4
    Ah, that makes a lot of sense. Thank you. – Maxx May 23 '13 at 02:39
  • 1
    Funny thing is, I've never seen it used in conjunction with throw. I guess it's just good practice. – Maxx May 23 '13 at 02:41
  • 3
    @Maxx: It's more to handle the cases where you end up with exceptions that weren't accounted for. `finally` will end up running regardless of how you exit the try/catch, even if it's due to an error you didn't know could happen. So it's a better place to put cleanup code and such. – cHao May 23 '13 at 02:43
  • 3
    Or when there is NO catch block. Then if any code inside the try block throws an error, the exception will get propagated up the stack to the calling routine, to be handled somewhere up the stack, or dealt with as an unhandled Exception. But the code in the finally block will STILL run. – Charles Bretana May 23 '13 at 02:44
  • Or when you rethrow an exception after some error-only cleanup. Or basically any other time you might leave the block via exception. In those cases, code after the block won't run. That's where `finally` comes in. – cHao May 23 '13 at 12:24
15
try
{
    throw new Exception("Error!");
}
catch (Exception ex)
{
    throw new Exception(ex, "Rethrowing!");
}
finally
{
    // Will still run even through the catch kicked us out of the procedure
}

Console.WriteLine("Doesn't execute anymore because catch threw exception");
jdl
  • 1,104
  • 8
  • 12
8

It really depends - some other answers have very good reasons to use a Finally block. But I think the best reason is because you're doing exception handling. Things you do in a Finally block typically involve cleaning up resources to ensure proper continuation, regardless of whether or not an exception was thrown - to me that's still part of the exception handling, at least part of a "try something" operation.

IMHO the Finally scope highlights the fact that its code contains stuff that deserves special attention in case of an exception.

Mathieu Guindon
  • 69,817
  • 8
  • 107
  • 235
4

finally block is guaranted to be excuted. So, in your example, results of both cases are looks same. but if you use return or throw in your catch block, you can see what is difference.

Outsider
  • 923
  • 1
  • 9
  • 20
1

Finally should be used to everything that needs to be done in order to keep a system consistent. This usually means release resources

Finally is always executed, no matter what exception was thrown. It should be used to release resources, in the following cases:

  • Finalize a connection
  • Close a file handler
  • Free memory
  • Close a database connection

Let me give a complete example. Imagine that that you are sending messages through the network. In pseudo-code:

// 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() 
}                                |

The only difference of both codes is when what is hold in the try block raises an exception that is not NetworkError, for example, MethodNotFound. In the first case, the method finalizes_connection() will be called, and in the second one, it will not.

A connection is naturally done through more than one program. So what happens in the case of a MethodNotFound exception to the other program? In the first case, your program will finish the connection and the other program and it will be happy. In the second case, the other program can be waiting for your response forever. What if the other program can only receive one connection per time? You just bugged the other program as well.

This would also apply for a file, for example, that you opened and other programs wouldn't be able to open for reading (in Windows). And for memory, it is never released and now you have a memory leak.

fotanus
  • 19,618
  • 13
  • 77
  • 111
0

finally runs for both try and catch. It ensures that it will run, but it is not 100% guaranteed it will [some errors stop execution of code]

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • But wouldn't that be the case simply placing it outside the try-catch block? – Qantas 94 Heavy May 23 '13 at 02:35
  • 1
    many times the catch will re-throw an error or stop execution, in which case the code in finally will still be run but code after the try catch block would not. – mconlin May 23 '13 at 02:37
0

try block needs at least one catch or a finally.after executing all catch blocks the finally block will be executed.You can add any logic you need there which should be done ultimately.

Sanjaya Liyanage
  • 4,706
  • 9
  • 36
  • 50
0

Its a good practice to use finally to handle program crashes. finally will always run .If the function exits inside of the try catch block, or another error is thrown in either the try or the catch, the finally will still execute. You won't get that functionality not using the finally statement.

argentum47
  • 2,385
  • 1
  • 18
  • 20
0

I don't know C#, but the purpose of a finally block in Java-ish languages is to ensure that system resources are relinquished, especially if garbage collection is irregular. It's the same principle for all. Consider the block

InputStream is = new FileInputStream("foo.txt");
OutputStream os = new FileOutputStream("D:/nonexistent/directory/bar.txt");
// Throws a FileNotFoundException.

The variable is is created successfully, and takes up system resources. Processes can only use a fixed number of file handles at a time. The variable os is never created, and an exception is thrown, and bubbles up to the caller. In the process, is goes out of scope, and becomes eligible for garbage collection.

However garbage collections are never guaranteed to happen, or they may happen at some indefinite time in the future. So, the system resources taken by is may never be freed. This can be costly, or can crash the program if it happens enough times. So, finally blocks were put into Java. Other languages have similar constructs. In C++, destructors are invoked deterministically. LISPy languages have unwind-protect, but those are usually packaged in with-foo macros.

In Java 6 and lower, one would do this:

try {
    is = new FileInputStream("foo.txt");
    os = new FileOutputStream("D:/nonexistent/directory/bar.txt");
    // work...
} finally {
    if (is != null) {
        try {
            is.close();
        } catch (IOException ignored) {}
    }
    if (os != null) {
        try {
            os.close();
        } catch (IOException ignored) {}
    } 
}

You can't just call is.close() because that might throw, and then os will never be closed. You have to check for null too. Sane people used Jakarta Commons-IO's IOUtils.closeQuietly() methods to replace the block:

} finally {
    IOUtils.closeQuietly(is);
    IOUtils.closeQuietly(os);
}

But Java 7 introduced a better solution: try-with-resources. C# 4 probably came first with something similar, Microsoft being quicker on the uptake than Snoracle.

try (
    is = new FileInputStream("foo.txt"),
    os = new FileOutputStream("D:/nonexistent/directory/bar.txt")
) {
    // work...
}
Eric Jablow
  • 7,874
  • 2
  • 22
  • 29
  • C# has `using`, which does about the same thing with implementations of `IDisposable` (the interface in .net that represents classes that hold native resources other than RAM). `using (var r = new SomeNativeResource()) { /* do stuff with r; */ }` pretty much translates to `var r = new SomeNativeResource(); try { /* do stuff with r; */ } finally { if (r != null) r.Dispose(); }`. That's been around since... 1.1 or earlier?...MSDN has a page for it for VS 2003, at least. – cHao May 23 '13 at 04:52
  • The original post was stated as being generic. I suppose you then need Finally blocks in C# if there are things you must do that you can't translate into an `IDisposable`. That's probably rare. – Eric Jablow May 23 '13 at 10:36
  • Yeah...`finally` blocks in C# aren't quite as common as in Java. `using` covers like 80% of the use cases. – cHao May 23 '13 at 11:56
0

finally always always runs. finally is like the catcher that never misses anything. In the example you mentioned, yes finally doesnt add any value. But finally is usually used to dispose/ release resources.

Jay Jay Jay
  • 1,970
  • 2
  • 25
  • 47