Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C# will the Finally block be executed in a try, catch, finally if an unhandled exception is thrown? [duplicate]

Tags:

c#

.net

finally

Another interview question which was expecting a true / false answer and I wasn't too sure.

Duplicate

  • In .NET, what if something fails in the catch block, will finally always get called?
  • Does a finally block always run?
  • Conditions when finally does not execute in a .net try..finally block
  • Will code in a Finally statement fire if I return a value in a Try block?
like image 206
Gais Avatar asked May 07 '09 10:05

Gais


2 Answers

finally is executed most of the time. It's almost all cases. For instance, if an async exception (like StackOverflowException, OutOfMemoryException, ThreadAbortException) is thrown on the thread, finally execution is not guaranteed. This is why constrained execution regions exist for writing highly reliable code.

For interview purposes, I expect the answer to this question to be false (I won't guarantee anything! The interviewer might not know this herself!).

like image 146
mmx Avatar answered Sep 21 '22 17:09

mmx


Generally the finally block is guaranteed to execute.

However, a few cases forces the CLR to shutdown in case of an error. In those cases, the finally block is not run.

One such example is in the presence of a StackOverflow exception.

E.g. in the code below the finally block is not executed.

static void Main(string[] args) {
   try {
      Foo(1);
   } catch {
      Console.WriteLine("catch");
   } finally {
      Console.WriteLine("finally");
   }
}

public static int Foo(int i) {
   return Foo(i + 1);
}

The other case I am aware of is if a finalizer throws an exception. In that case the process is terminated immediately as well, and thus the guarantee doesn't apply.

The code below illustrates 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();
   }
}

In both cases the process terminates before both catch and finally.

I'll admit that the examples are very contrived, but they are just made to illustrate the point.

Fortunately neither happens very often.

like image 22
Brian Rasmussen Avatar answered Sep 21 '22 17:09

Brian Rasmussen