For some reason within my console application I cannot get my finally block to run. I was writing this code to test how the finally block works so it is very simple:
static void Main()
{
int i = 0;
try
{
int j = 1 / i; // Generate a divide by 0 exception.
}
finally
{
Console.Out.WriteLine("Finished");
Console.In.ReadLine();
}
}
At first I had the problem described here but then I tried to run the program outside Visual Studio I got a "Program has stopped responding" error.
Because you do not have a top level exception handler, the .Net runtime is catching the exception for you and aborting the program before the finally has a chance to run. This illustrates the point:
static void Main()
{
try
{
int i = 0;
try
{
int j = 1 / i; // Generate a divide by 0 exception.
}
finally
{
Console.Out.WriteLine("Finished");
Console.In.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
With this code, the exception is now handled a try...catch higher up in the calling chain (it just happens to be in the same method), so the embedded finally will be executed. The catch need not be in the same function where the exception is being raised, it can be anywhere in the calling chain.
Edit: initially it may seem uncertain when and where an exception will be caught by your program. But think about the boundaries of your application, where the outside world interacts with your code - normally they are limited and well defined. So for a console application, the boundary is the Main method, and this is where you can put the top level exception handler. For a Web forms application, the boundary includes things like button click events (the user is interacting with your UI), so you could have exception handlers in there too. For a class library the boundary is generally the boundary of the application that calls the library, not the library itself. So do not catch exceptions in the library (unless you can sensibly recover from them), but let them bubble up to the calling application instead.
Wanted to add my own findings here as the behavior here is certainly strange - and as such, the accepted answer is not entirely correct.
Given the following sample:
static void Main(string[] args)
{
try{
throw new Exception("");
} finally {
Console.WriteLine("I am never called!");
Console.ReadLine();
}
}
The finally block is actually executed IF we choose to CANCEL out of the Windows Error Reporting Dialog, as such:
HOWEVER, if we allow the Windows Error Reporting Dialog to "complete", so we get the option to "Debug" or "Close Program", then the finally block is NOT executed.
Which to me indicates that the .NET Runtime WILL actually run all finally blocks, regardless of experiencing a "Unhandled top level Exception", and that what's preventing it from doing so is actually Windows (if you select "Close Program") or the Visual Studio Debugger (if you select "Debug" or is starting with the debugger attached)... As they kill the process before the Runtime as a chance to proceed.
Any thoughts?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With