Is the C # "finally" block ALWAYS executed?

Possible duplicate:
Will the code in the declaration be Final if I return its value in the Try block?

Consider the following C # code. Is the finally block running?

public void DoesThisExecute() { string ext = "xlsx"; string message = string.Empty; try { switch (ext) { case "xls": message = "Great choice!"; break; case "csv": message = "Better choice!"; break; case "exe": message = "Do not try to break me!"; break; default: message = "You will not win!"; return; } } catch (Exception) { // Handle an exception. } finally { MessageBox.Show(message); } } 

Ha, after I finished writing this, I realized that I could test it myself in Visual Studio. However, please feel free to reply!

+49
c # try-catch
Jul 09 '10 at 19:49
source share
11 answers
+8
Jul 09 '10 at 19:51
source share

No no. It will always be executed provided that the application is still running (with the exception of the FastFail exception, MSDN link , as others have noted). It will be executed when it exits the try / catch block of the block.

It will not be executed if the application crashes: it will be killed by the destruction process command, etc. This is very important, because if you write code that absolutely expects to be launched, for example, manual rollback, and if not another, it will be automatically fixed, you can run a script that the application interrupts before this happens. Honestly, this is an external scenario, but it is important to consider in these situations.

+67
Jul 09 '10 at 19:53
source share

From the msdn specification of the C # try statement.

The finally block statements are always executed when the control leaves an attempt expression. Is it true whether control transfer occurs as a result of normal execution, as a result of a break, continued, goto or return, or as a result of the distribution of a try statement exception. try instructions.

Source Link:

http://msdn.microsoft.com/en-us/library/aa664733(v=VS.71).aspx

There are times when the finally block will not execute.

  • Environment.FailFast
  • Fancy execeptions
  • Power failure
+40
Jul 09 '10 at 19:52
source share

It is not entirely true that finally will always be executed. See this answer from Haacked :

Two possibilities:

  • StackOverflowException
  • ExecutingEngineException

The finally block will not be executed when a StackOverflowException exists because there is no place on the stack to even execute any code. It will also not be called when there is a ExecutingEngineException, which is very rare.

In fact, for any kind of asynchronous exception (for example, StackOverflowException , OutOfMemoryException , ThreadAbortException ), the execution of the finally block is not guaranteed.

However, these exceptions are exceptions from which it is usually impossible to recover, and in most cases your process will still exit.

In fact, there is also at least one other case where finally not executed, as described by Brian Rasmussen in the now deleted question :

In another case, I know that if the Finalizer throws an exception. This is if the process is completed immediately, and therefore the warranty does not apply.

The code below shows the problem

 static void Main(string[] args) { try { DisposableType d = new DisposableType(); d.Dispose(); d = null; GC.Collect(); GC.WaitForPendingFinalizers(); } catch { Console.WriteLine("catch"); } finally { Console.WriteLine("finally"); } } public class DisposableType : IDisposable { public void Dispose() { } ~DisposableType() { throw new NotImplementedException(); } } 

A reliable try / catch / will finally have to use Limited Runtime Areas (CERs) . An example is provided by MSDN:

 [StructLayout(LayoutKind.Sequential)] struct MyStruct { public IntPtr m_outputHandle; } sealed class MySafeHandle : SafeHandle { // Called by P/Invoke when returning SafeHandles public MySafeHandle() : base(IntPtr.Zero, true) { } public MySafeHandle AllocateHandle() { // Allocate SafeHandle first to avoid failure later. MySafeHandle sh = new MySafeHandle(); RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { MyStruct myStruct = new MyStruct(); NativeAllocateHandle(ref myStruct); sh.SetHandle(myStruct.m_outputHandle); } return sh; } } 

An excellent source of information is the following article:

Top reliability recommendations

+27
Jul 09 '10 at 19:57
source share

From MSDN try-finally (C # link)

The finally block is useful for cleaning up any resources allocated to the try block, as well as running any code that should be executed, even if it is an exception. Control is always passed to the finally block as the try block exits .

+4
Jul 09 '10 at 19:52
source share

The finally block will work right between these lines:

 message = "You will not win!"; return; 
+2
Jul 09 '10 at 19:58
source share

Yes, finally always executed, now whether the code in the finally block will throw an exception is another story.

+1
Jul 09 '10 at 19:51
source share

Yes, under normal circumstances (as many others have pointed out).

The finally block is useful for cleaning up any resources allocated to the try block, as well as running any code that should be executed, even if it is an exception. Control is always passed to the finally block as the try block exits.

While catch is used to handle exceptions that occur in a block statement, it is finally used to ensure that a block of code execution is executed regardless of how the previous block attempt is completed.

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

+1
Jul 09 '10 at 19:52
source share

Correct answer: Yes.

Try debugging your program and place a breakpoint and see how the control still falls into the finally block.

+1
Jul 09 '10 at 19:56
source share

No, it is not.

There is only one way around it, and that is Environment.FailFast() . See http://msdn.microsoft.com/de-de/library/ms131100.aspx . In each other case, the execution of finalizers is guaranteed; -)

The FailFast method writes a line message to a Windows application. The event log creates a dump of your application and then terminates the current process. Message lines are also included in the Microsoft bug report.

Use the FailFast method instead of Exit the application if the state of your application is damaged without repair, and the execution of your application try / finally blocks and finalizers will be corrupted program resources.

+1
Jul 09 '10 at 19:57
source share

The simple answer is yes. But there are some β€œexceptions” to the rule.

0
Jul 09 '10 at 19:51
source share



All Articles