Does finally block execute if there is an unhandled exception? - c#

We know that the code in the finally block is guaranteed to execute, regardless of whether the exception is caught. But let's say we have the following code:
class Program {
static void Main(string[] args) {
try {
int a = 0;
int b = 2021 / a;
}
finally {
System.Diagnostics.Debug.WriteLine("finally execute");
}
}
}
I cannot use Console.WriteLine since an unhandled exception terminates a process, no output written to the console, so I use System.Diagnostics.Debug.WriteLine, hopefully I can see "finally execute" displayed in the VS debug window.
When I execute the code, I didn't find "finally execute" in debug window, which means finally block won't execute if there is an unhandled exception.
If you look at this link https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally
It does say:
Part one
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.
Part Two
The only cases where finally clauses don't run involve a program being immediately stopped. An example of this would be when InvalidProgramException gets thrown because of the IL statements being corrupt. On most operating systems, reasonable resource cleanup will take place as part of stopping and unloading the process.
My questions are:
Q1-What does "dependent on how your computer is set up" in Part One mean?
Q2-If it is dependent on how the computer is set up, then what does Part Two mean? The exception in my example is DivideByZeroException, not InvalidProgramException, so why the finllay block still doesn't execute

As per my understanding finally will execute in this case. As you have not use Catch block it throw unhandled exception to the process level so any statement after finally block will not execute.
This is the code.
using System;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
try
{
int a = 0;
int b = 2021 / a;
}
finally
{
Console.WriteLine("finally execute");
}
Console.WriteLine("Complete");
Console.ReadLine();
}
}
}
Sample output.

Related

Why finally block may not execute when exception is thrown?

For a long time I thought that it allows me to free up all the resources in the finally block and I thought that if an exception happens in the try block, then the resources will still be free up in the finally block. But that seems not to be the case.
I have the following piece of code:
using System;
public sealed class Program
{
public static void Main()
{
try {
int zero = 0;
int i = 1/zero;
} finally {
Console.WriteLine("divide by zero"); //the line is never called
}
}
}
I never reach the line which prints to the console. That means that I will not be able to free up resource in finally block in this case on the exception being thrown inside the try block.
So, I believe there are two things: either I am missing something or the try + finally combination has no use cases in the C#. The second statement makes sense, because I will get the same functionality as is produced by the above code with the code below:
using System;
public sealed class Program
{
public static void Main()
{
int zero = 0;
int i = 1/zero;
Console.WriteLine("divide by zero"); //the line is never called
}
}
But I am afraid that I might be missing something here. So, could someone confirm that the combination is useless or prove that it is not, please?
UPDATE
After the comment which is able to call the finally block in its fiddle, I checked once more in the VS Code, and still I see no output.
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.
try/catch/finally has nothing to do with freeing up resources. This is strictly application flow and error handling construct. You live in the managed code and garbage collector frees up resources. This construct does the following
try
{
int zero = 0;
int i = 1/zero;
}
catch (DividedByZeroException ex)
{
Console.WriteLine(Exception handled);
throw; // propagate ex to caller
}
finally
{
Console.WriteLine("Method ended execution"); // called with or without exception
}
I believe this is because you have VS to break on unhandled errors and thus VS steps in displaying the exception. If you compile it and run it manually on the command line I believe you will see "divide by zero". Also, instead of changing your VS settings, you can 'handle' the error and then should see the behavior you expect.
Example:
using System;
public sealed class Program
{
public static void Main()
{
try
{
int zero = 0;
int i = 1 / zero;
}
catch
{
}
finally
{
Console.WriteLine("divide by zero");
}
}
}

Why Dispose is not called even with using-statement?

I have this console application (.NET Framework 4.5.2):
class Program
{
static void Main(string[] args)
{
using (var result = new Result())
{
result.Test();
}
}
}
public class Result : IDisposable
{
public void Test()
{
int a = 1;
int b = 1 / (a - 1);
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
}
Why Dispose method is not called? A breakpoint is not hit in Dispose after the DivideByZero-exception and there is no output on the console (because the app exits).
As per MS Docs: try-finally (C# Reference)
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.
As you are not catching the DivideByZero exception and let it be unhandled, on your machine and setup it must be bringing down the application before any other line of code is run and therefore not running the finally block.
As #Evk has pointed out in below comment, if I run it without attaching debugger, it unwinds the exceptions correctly and executes the finally block. Learn something new everyday.
As per Eric Lippert's answer to Finally Block Not Running?
Think about how awful that situation is: something unexpected has
happened that no one ever wrote code to handle. Is the right thing to
do in that situation to run even more code, that was probably also not
built to handle this situation? Possibly not. Often the right thing to
do here is to not attempt to run the finally blocks because doing so
will make a bad situation even worse. You already know the process is
going down; put it out of its misery immediately.
In a scenario where an unhandled exception is going to take down the
process, anything can happen. It is implementation-defined what
happens in this case: whether the error is reported to Windows error
reporting, whether a debugger starts up, and so on. The CLR is
perfectly within its rights to attempt to run finally blocks, and is
also perfectly within its rights to fail fast. In this scenario all
bets are off; different implementations can choose to do different
things.

Environment.FailFast in c# application

I'd like to understand the Environment.FailFast rule in c# application. So , I made this code :
public static void Main()
{
string strInput = GetString();
Console.WriteLine(strInput);
Console.ReadKey();
}
private static string GetString()
{
Console.WriteLine("Get string");
string s = Console.ReadLine();
try
{
if (s == "Exit")
{
Environment.FailFast("Erreur fatale");
return s;
}
else
{
return s;
}
}
catch (Exception)
{
return "catch";
}
finally
{
s += "finally";
}
}
As I learned, the message are written to the Windows application event log and the application is terminated.
When I run the application and put Exit as a string :
The debbugger indicates an error :
I try to find the event log file, as indicated in msdn, but I don't find it
I don't understand why the application didn't shut down without throwing the exception? For the second point, How can I find the log file in my PC?
Environment.FailFast(string) exits the application immediately, without allowing any catch statements or finalizers to be run on the object.
You should only use this method if your application's state is at a point where it can never be recovered, and exiting the application is the only way to ensure something far worse than crashing does not happen. In your sample, using Environment.Exit with an exit code is more suitable, as it appears to be a graceful exit, rather than one forced through corrupt state.
In general, it is recommended to not use FailFast while the debugger is attached - this is documented in the System.Diagnostics.Assert class:
// However, in CLR v4, Environment.FailFast when a debugger is attached gives you an MDA
// saying you've hit a bug in the runtime or unsafe managed code, and this is most likely caused
// by heap corruption or a stack imbalance from COM Interop or P/Invoke. That extremely
// misleading error isn't right, and we can temporarily work around this by using Environment.Exit
// if a debugger is attached. The right fix is to plumb FailFast correctly through our native
// Watson code, adding in a TypeOfReportedError for fatal managed errors. We may want a contract-
// specific code path as well, using COR_E_CODECONTRACTFAILED.
Which means the exception you're seeing in Visual Studio is down to a bug in the CLR, and could be safely ignored.
Their work around is as follows:
if (Debugger.IsAttached)
Environment.Exit(COR_E_FAILFAST);
else
Environment.FailFast(message);
Which means that while running with the debugger attached, you won't get the Event Log message written, while in release you do.
I've reconstructed your problem with the following piece of code:
static void Main(string[] args)
{
try
{
Console.WriteLine("Foo");
Environment.FailFast("WOHO!");
}
finally { }
}
When running this under the debugger, I didn't see any exceptions registered either. Running this without the debugger (Ctrl + F5) makes the exception appear in the Event Viewer properly (see #aevitas answer or read this for why that happens):

C# - Application terminates unexpectedly without leaving traces

I have a simple C# application/game using SFML.Net that currently stops running / terminates within 1 or 2 seconds after being executed without any warning, exception, etc. whatsoever. Consider the following code:
public static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
--> The following two lines are run
Console.WriteLine("Hello");
Console.WriteLine("Please don't go...");
// Run the game
try
{
--> This line is reached
Game.Run();
}
catch (Exception e)
{
--> This line is never reached
Console.WriteLine(e.Message.ToString());
}
--> These lines are never reached
Console.WriteLine("Noone ever comes here, I feel so lonely... :(");
Console.ReadKey();
}
}
At this point you probably expect that something is wrong with the Game.Run() method. The odd thing is that the first line of the method is never reached according to the VS Debugger.
public static void Run()
{
try
{
--> Never reached
LoadContent();
// Do stuff here
while (window.IsOpen())
{
// The classic game loop
}
}
catch (Exception e)
{
--> Never reached
Console.WriteLine(e.Message.ToString());
Console.ReadKey();
}
}
My guess is that either:
You are getting an Access Violation Exception which cannot be caught.
OR
There is some other exception before you go into the Run method that is not handled. In order to verify that, make sure your debugger stops on first chance exceptions.
It would also be helpful if you specify:
How do you know that the first line is never reached? breakpoint? output?
What happens when you expect this function to be entered? does your application exist?
Are you debugging step by step?
My Guess is that the exception is being thrown by another thread. You cannot catch an exception thrown from another thread in the main thread. So your breakpoint in catch will never be hit. Btw did you try having a breakpoint in your UnhandledExceptionEventHandler method OnUnhandledException? That is where all unhandled exceptions go! Hope this helps.
You can get all called functions stack in your application until the termination point with the Runtime Flow tool (30 day trial, developed by me) and find what actually happens.
I came back to this after a couple of months and realized how silly my mistake was. Apparently unmanaged code debugging wasn't enabled by default (this was my first time using VS2012), and this exception was being thrown from the base C++ libs of SFML.
For those who don't know, to enable unmanaged debugging:
Project > Properties > Debug > Select "Enable unmanaged code debugging"

Evasive exceptions and "a function evaluation has timed out"

Background
In my utilities library (Shd.dll) I have a class called AsyncOperation. To put it simply, it's a base class for types that encapsulate a potentially long running operation, executes it on a background thread, and it supports pause/resume, cancellation and progress reporting. (It's like a BackgroundWorker, just knows more things.)
In the user code you can use it like this:
class MyOperation : AsyncOperation
{
public MyOperation() : base(null, AsyncOperationOptions.Cancelable | AsyncOperationOptions.Pausable) {}
protected override void RunOperation(AsyncOperationState operationState, object userState)
{
...
operationState.ThrowIfCancelled();
}
}
var op = new MyOperation();
op.Start();
...
op.Cancel();
operationState.ThrowIfCancelled() does exactly what its name suggests: if Cancel() was called earlier by another thread, it throws an internal exception (AsyncOperationCancelException), which is then handled by the AsyncOperation type, like this:
private void _DoExecute(object state)
{
// note that this method is already executed on the background thread
...
try
{
operationDelegate.DynamicInvoke(args); // this is where RunOperation() is called
}
catch(System.Reflection.TargetInvocationException tiex)
{
Exception inner = tiex.InnerException;
var cancelException = inner as AsyncOperationCancelException;
if(cancelException != null)
{
// the operation was cancelled
...
}
else
{
// the operation faulted
...
}
...
}
...
}
This works perfectly. Or so I thought for the past year, while I was using this in numerous scenarios.
The actual problem
I'm building a class that uses System.Net.WebClient to upload potentially large number of files via FTP. This class is built using the AsyncOperation base class as described above.
For accurate progress reports, I use WebClient.UploadFileAsync(), which complicates the code, but the relevant parts look like this:
private ManualResetEventSlim completedEvent = new ManualResetEventSlim(false);
private void WebClient_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
...
if (OperationState.IsCancellationRequested)
{
_GetCurrentWebClient().CancelAsync();
}
}
private void WebClient_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
...
_UploadNextFile();
}
private void _UploadNextFile()
{
if (OperationState.IsCancellationRequested || ...)
{
this.completedEvent.Set();
return;
}
...
}
protected override void RunOperation(AsyncOperationState operationState, object userState)
{
...
_UploadNextFile();
this.completedEvent.Wait();
operationState.ThrowIfCancelled(); // crash
...
}
As you can see, I marked the line where the crash occurs. What exactly happens is that when execution hits that line (I put a break point right over it, so I know this is the exact line), Visual Studio 2010 freezes for about 15 seconds, and then the next thing I see is the source code of AsyncOperationState.ThrowIfCancelled():
public void ThrowIfCancelled()
{
if(IsCancellationRequested)
{
throw new AsyncOperationCancelException();
}
} // this is the line the debugger highlights: "An exception of type AsyncOperationCancelException' occured in Shd.dll but was unhandled by user code."
I tried putting breakpoints to where the exception should have been caught, but the execution never reaches that catch {} block.
The other weird this is that at the end it also writes the following: "Function evaluation disabled because a previous function evaluation timed out." I Googled this problem, and tried everything that was suggested (disabled implicit property evaluation, removed all breakpoints), but nothing helped so far.
Here are two screenshots that illustrate the problem:
http://dl.dropbox.com/u/17147594/vsd1.png
http://dl.dropbox.com/u/17147594/vsd2.png
I'm using .NET 4.0. Any help would be very much appreciated.
When the Visual Studio debugger is attached to an application, it gets notified whenever an exception is thrown, before the running code gets the chance to handle it. This is called a first-chance exception, and VS can be configured to break execution when a certain exception type is thrown.
You can specify debugger behavior for each exception type separately using the Exceptions window (Debug menu). By default, all exceptions have the "User-unhandled" checkbox checked, meaning that only unhandled exceptions will break execution. Setting the "Thrown" checkbox for a certain exception type forces VS to break execution even if the exception will be handled, but only for that exception type (not for derived types). If a handler exists, once you resume execution (by pressing F5), the exception will be caught normally.
I would guess that your custom exception was added to the list of exceptions in the Exceptions window (which you can check by using the Find button inside the window).
[Edit]
According to my tests, it also happens when DynamicInvoke is used in .NET 4, regardless of the Exceptions window setting. Yesterday I was using VS2008 and I couldn't reproduce it, but it does seem like odd behavior now.
This is the test I tried (sorry for the brief formatting, but it's fairly simple):
Action<int> a = i => { throw new ArgumentException(); };
// When the following code is executed, VS2010 debugger
// will break on the `ArgumentException` above
// but ONLY if the target is .NET 4 (3.5 and lower don't break)
try { a.DynamicInvoke(5); }
catch (Exception ex)
{ }
// this doesn't break
try { a.Invoke(5); }
catch (Exception ex)
{ }
// neither does this
try { a(5); }
catch (Exception ex)
{ }
My only guess is that exception handling done inside InvokeMethodFast (which is an InternalCall method) has somehow changed. DynamicInvoke code has changed between versions 4 and prior, but there is nothing which would indicate why VS2010 debugger is unable to see that there is an exception handler inside that method call.
“a function evaluation has timed out”
You don't have a real problem, this is a debugger artifact. It is triggered by the way the debugger evaluates watch expressions. When you start a .NET program with the debugger attached, the program will have a dedicated thread, solely for use by the debugger. Whenever the debugger needs to evaluate a watch expression, it uses that thread to execute the expression code. The result is then displayed in the watch window.
Which works very well and gives the debugger a lot of capabilities. Including calling a method in your program when a breakpoint is active. Rather necessary, a lot of object values you'd be interested in are exposed as properties. Which are implemented as methods in the generated code.
That debugger thread can however cause trouble. An obvious case is where you try to evaluate a property that takes a lock. If you break execution at a stage where that lock is owned by another thread then the debugger thread is going to hit a brick wall. It trundles for a while, notices that the debugger thread isn't completing, then gives up and displays "a function evaluation has timed out" as the watch value. It also remembers that it failed, any watches you try later will produce "Function evaluation disabled because a previous function evaluation timed out". Necessarily so, the debugger thread is still stuck in a rut.
Similar kind of problem in your code. The probable scenario there is that the thread you need to get the operation completed got suspended by the debugger break. The only decent advice to give here is to be careful with your watch expressions.
If your try catch logic is running on a different thread than the code that actually throws the exception, then the catch block will never execute.
Consider the following sample:
class Program
{
static void Main(string[] args)
{
try
{
Thread thread = new Thread((s) =>
{
throw new Exception("Blah");
});
thread.Start();
}
catch (Exception ex)
{
Console.WriteLine("Exception caught: {0}", ex);
}
Console.ReadKey();
}
}
The catch block of course does not execute since the exception was thrown on a different thread.
I'm suspecting that you could be experiencing something similar. If you want your catch block to execute, it must be on the same thread that the error is being thrown on.
Good luck!

Categories