Does the C# "Finally" Block Always Execute

Does the C# finally block ALWAYS execute?

yes it does :-) http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

When does a finally block execute if the catch block contains a continue statement?

Think of it as a try/finally block with catch expressions optional. Both continue statements in your code would pop the execution stack out of the catch which would place execution in the finally block before allowing the loop to continue. Any time there is a try/finally block, finally will always be executed.

If I return out of a try/finally block in C# does the code in the finally always run?

Under normal conditions, code in a finally block will be executed regardless of what happens inside the try or catch blocks. It doesn't matter if you return from the method or not.

There are cases where this is not true. For example if the code in the finally block throws an exception, then it will stop executing like any other block of code.

Eric Lippert has written a much more comprehensive answer that outlines additional cases: https://stackoverflow.com/a/10260233/53777

In regards to goto, the answer is still yes. Consider the following code:

try
{
Console.WriteLine("Inside the Try");
goto MyLabel;
}
finally
{
Console.WriteLine("Inside the Finally");
}

MyLabel:
Console.WriteLine("After the Label");

The output produced is this:

Inside the Try

Inside the Finally

After the Label

Exception in catch block means the finally block never executes?


What and why it happens

The result depends on what button you click when the program crashes. If you're slow, the Windows Error Reporting (WER) dialog will show "Debug" and "Close program". If you press the "Close program" button, the program is terminated by the operationg system without any chance of writing something else to console.

Screenshot: close program

If you're fast enough to hit the "Cancel" button, then the Windows Error Reporting part will be cancelled and control goes back to your program. It will then write "Carrot" to the Console.

Screenshot: cancel

Therefore, this is not a .NET issue but it's a matter on how Windows reacts to exception dispatching.

How to get control over it

To disable the WER dialog, you can use WerAddExcludedApplication . To get rid of the Debug dialog, you can use SetErrorMode.

Please make yourself familiar with the disadvantages of using those methods. Read Raymond Chen's comments on WerAddExcludedApplication and check whether SetThreadErrorMode might be in favor.

Your code may then look like this:

using System;
using System.Runtime.InteropServices;

namespace ExceptionInCatch
{
class Program
{
[DllImport("wer.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int WerAddExcludedApplication(String pwzExeName, bool bAllUsers);

[Flags]
public enum ErrorModes : uint
{
SYSTEM_DEFAULT = 0x0,
SEM_FAILCRITICALERRORS = 0x0001,
SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
SEM_NOGPFAULTERRORBOX = 0x0002,
SEM_NOOPENFILEERRORBOX = 0x8000,
SEM_NONE = SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX
}

[DllImport("kernel32.dll")]
static extern ErrorModes SetErrorMode(ErrorModes uMode);


public static void Main(string[] args)
{
var executableName = AppDomain.CurrentDomain.FriendlyName;
WerAddExcludedApplication(executableName, false);
SetErrorMode(ErrorModes.SEM_NONE);
try
{
throw new Exception("Apple");
}
catch (Exception ex)
{
throw new Exception("Banana");
}
finally
{
// This line will now execute
Console.WriteLine("Carrot");
}
}
}
}

Why finally block may not execute when exception is thrown?

You're assumptions are incorrect (sometimes) https://dotnetfiddle.net/hjqmOS

try-finally (C# Reference)

By using a finally block, you can clean up any resources that are
allocated in a try block, and you can run code even if an exception
occurs in the try block. Typically, the statements of a finally block
run when control leaves a try statement. The transfer of control can
occur as a result of normal execution, of execution of a break,
continue, goto, or return statement, or of propagation of an exception
out of the try statement.

There are cases when it doesn't run though

Within a handled exception, the associated finally block is guaranteed
to be run. However, if the exception is unhandled, execution of the
finally block is dependent on how the exception unwind operation is
triggered
. That, in turn, is dependent on how your computer is set up.

Here is the important part

Usually, when an unhandled exception ends an application, whether or
not the finally block is run is not important. However, if you have
statements in a finally block that must be run even in that situation,
one solution is to add a catch block to the try-finally statement.
Alternatively, you can catch the exception that might be thrown in the
try block of a try-finally statement higher up the call stack.

Does a finally block always get executed in Java?

Yes, finally will be called after the execution of the try or catch code blocks.

The only times finally won't be called are:

  1. If you invoke System.exit()
  2. If you invoke Runtime.getRuntime().halt(exitStatus)
  3. If the JVM crashes first
  4. If the JVM reaches an infinite loop (or some other non-interruptable, non-terminating statement) in the try or catch block
  5. If the OS forcibly terminates the JVM process; e.g., kill -9 <pid> on UNIX
  6. If the host system dies; e.g., power failure, hardware error, OS panic, et cetera
  7. If the finally block is going to be executed by a daemon thread and all other non-daemon threads exit before finally is called

Execution order of try, catch and finally block

Yes, the finally block of the try-catch will be executed in order as you would expect, and then execution will proceed onto the rest of the code (after completing the entire try-catch-finally block).

You can think of the entire try-catch-finally block as a single component that would function just like any other method call would (with code being executed before and after it).

// Execute some code here

// try-catch-finally (the try and finally blocks will always be executed
// and the catch will only execute if an exception occurs in the try)

// Continue executing some code here (assuming no previous return statements)

Example

try 
{
Console.WriteLine("1");
throw new Exception();
}
catch(Exception)
{
Console.WriteLine("2");
}
finally
{
Console.WriteLine("3");
}
Console.WriteLine("4");
return;

You can see an example of this in action here that yields the following output :

1
2
3
4

How does the try catch finally block work?

Yes, the finally block gets run whether there is an exception or not.


Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ] --RUN ALWAYS
End Try

See: http://msdn.microsoft.com/en-us/library/fk6t46tz%28v=vs.80%29.aspx



Related Topics



Leave a reply



Submit