Why Dispose is not called even with using-statement? - c#

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.

Related

Simulate Exception in Environment.Exit

A production console application that is shut down via Environment.Exit(0) every night prior midnight, occasionally experiences an exception during .Exit() which leaves the console application hanging, with an "Application has stopped working" screen.
This causes the process not to clean up properly and a relaunch after midnight fails because the prior process is still lingering.
Since I couldn't pin down what causes the exception in Environment.Exit, I'd like to at least handle it gracefully when it occurs and ensure that the process shuts down entirely. To do that, I'd like to simulate a crash after .Exit() but I wasn't able to find a scenario yet that would produce an exception during .Exit().
Does anyone have an idea how an exception during Environment.Exit could be simulated?
Sure, it's easy enough to duplicate:
private static void Main()
{
try
{
new ItsATrap();
Environment.Exit(0);
}
catch (Exception ex)
{
Console.WriteLine("During exit: {0}", ex);
}
}
private class ItsATrap
{
~ItsATrap()
{
throw new InvalidOperationException("Ooops!");
}
}
Note that the During exit text is never printed in the example above.
You can catch unhandled exceptions by installing a handler like this:
AppDomain.CurrentDomain.UnhandledException += (sender, args)
=> Console.WriteLine("Unhandled: {0}", args.ExceptionObject);
This way you have an opportunity to log them.
So... check your finalizers to see if they can throw.
Also, make sure they don't use other managed resources, as the finalization order isn't deterministic. As usual, Eric Lippert has some good articles to read on the subject.
You have an XY-problem here. You want to simulate an exception because you have no idea what else you could do. Instead of simulating something you don't exactly know, you should try to find out the real cause of the issue and fix it.
Collect a crash dump (MSDN) and load it into Visual Studio. As long as it's somewhere in your C# code, it should show you the line number.
See also: How do I take a good crash dump for .NET? here on Stack Overflow.
Modifying your code as proposed in other answers may change the timing and could just make the exception less likely or occur in different positions. Be happy that you can reproduce the problem and fix it instead of diluting it.
Use of a disposed/finalized object can probably cause it. This happens because there is no fixed order for finalization, so for example an hand-made logger that tries to write something on a Stream that has been finalized will cause an exception (hand made because "professional" loggers know of this :-) ).
You could try installing a first-chance exception handler just before calling the Environment.Exit that logs every exception that happens during this time. Something like:
object lck = new object();
AppDomain.CurrentDomain.FirstChanceException += (sender, e) =>
{
lock (lck)
{
File.AppendAllText("log.txt", string.Format("{0}: {1}", DateTime.Now, e.Exception.ToString()));
}
};
Environment.Exit(0);

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):

Handling exceptions thrown by "Dispose" while unwinding nested "using" statements

Apparently, some exceptions may just get lost while using nested using statement. Consider this simple console app:
using System;
namespace ConsoleApplication
{
public class Throwing: IDisposable
{
int n;
public Throwing(int n)
{
this.n = n;
}
public void Dispose()
{
var e = new ApplicationException(String.Format("Throwing({0})", this.n));
Console.WriteLine("Throw: {0}", e.Message);
throw e;
}
}
class Program
{
static void DoWork()
{
// ...
using (var a = new Throwing(1))
{
// ...
using (var b = new Throwing(2))
{
// ...
using (var c = new Throwing(3))
{
// ...
}
}
}
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
// this doesn't get called
Console.WriteLine("UnhandledException:", e.ExceptionObject.ToString());
};
try
{
DoWork();
}
catch (Exception e)
{
// this handles Throwing(1) only
Console.WriteLine("Handle: {0}", e.Message);
}
Console.ReadLine();
}
}
}
Each instance of Throwing throws when it gets disposed of. AppDomain.CurrentDomain.UnhandledException never gets called.
The output:
Throw: Throwing(3)
Throw: Throwing(2)
Throw: Throwing(1)
Handle: Throwing(1)
I prefer to at least be able to log the missing Throwing(2) and Throwing(3). How do I do this, without resorting to a separate try/catch for each using (which would kinda kill the convenience of using)?
In real life, those objects are often instances of classes over which I have no control. They may or may not be throwing, but in case they do, I'd like to have an option to observe such exceptions.
This question came along while I was looking at reducing the level of nested using. There's a neat answer suggesting aggregating exceptions. It's interesting how this is different from the standard behavior of nested using statements.
[EDITED] This question appears to be closely related:
Should you implement IDisposable.Dispose() so that it never throws?
There's a code analyzer warning for this. CA1065, "Do not raise exceptions in unexpected locations". The Dispose() method is on that list. Also a strong warning in the Framework Design Guide, chapter 9.4.1:
AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).
This goes wrong because the using statement calls Dispose() inside a finally block. An exception raised in a finally block can have an unpleasant side-effect, it replaces an active exception if the finally block was called while the stack is being unwound because of an exception. Exactly what you see happening here.
Repro code:
class Program {
static void Main(string[] args) {
try {
try {
throw new Exception("You won't see this");
}
finally {
throw new Exception("You'll see this");
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
What you are noticing is a fundamental problem in the design of Dispose and using, for which no nice solution as yet exists. IMHO the best design would be to have a version of Dispose which receives as an argument any exception which may be pending (or null, if none is pending), and can either log or encapsulate that exception if it needs to throw one of its own. Otherwise, if you have control of both the code which could cause an exception within the using as well as within the Dispose, you may be able to use some sort of outside data channel to let the Dispose know about the inner exception, but that's rather hokey.
It's too bad there's no proper language support for code associated with a finally block (either explicitly, or implicitly via using) to know whether the associated try completed properly and if not, what went wrong. The notion that Dispose should silently fail is IMHO very dangerous and wrongheaded. If an object encapsulates a file which is open for writing, and Dispose closes the file (a common pattern) and the data cannot be written, having the Dispose call return normally would lead the calling code to believe the data was written correctly, potentially allowing it to overwrite the only good backup. Further, if files are supposed to be closed explicitly and calling Dispose without closing a file should be considered an error, that would imply that Dispose should throw an exception if the guarded block would otherwise complete normally, but if the guarded block fails to call Close because an exception occurred first, having Dispose throw an exception would be very unhelpful.
If performance isn't critical, you could write a wrapper method in VB.NET which would accept two delegates (of types Action and an Action<Exception>), call the first within a try block, and then call the second in a finally block with the exception that occurred in the try block (if any). If the wrapper method was written in VB.NET, it could discover and report the exception that occurred without having to catch and rethrow it. Other patterns would be possible as well. Most usages of the wrapper would involve closures, which are icky, but the wrapper could at least achieve proper semantics.
An alternative wrapper design which would avoid closures, but would require that clients use it correctly and would provide little protection against incorrect usage would have a usage batter like:
var dispRes = new DisposeResult();
...
try
{
.. the following could be in some nested routine which took dispRes as a parameter
using (dispWrap = new DisposeWrap(dispRes, ... other disposable resources)
{
...
}
}
catch (...)
{
}
finally
{
}
if (dispRes.Exception != null)
... handle cleanup failures here
The problem with this approach is that there's no way to ensure that anyone will ever evaluate dispRes.Exception. One could use a finalizer to log cases where dispRes gets abandoned without ever having been examined, but there would be no way to distinguish cases where that occurred because an exception kicked code out beyond the if test, or because the programmer simply forgot the check.
PS--Another case where Dispose really should know whether exceptions occur is when IDisposable objects are used to wrap locks or other scopes where an object's invariants may temporarily be invalidated but are expected to be restored before code leaves the scope. If an exception occurs, code should often have no expectation of resolving the exception, but should nonetheless take action based upon it, leaving the lock neither held nor released but rather invalidated, so that any present or future attempt to acquire it will throw an exception. If there are no future attempts to acquire the lock or other resource, the fact that it is invalid should not disrupt system operation. If the resource is critically necessary to some part of the program, invalidating it will cause that part of the program to die while minimizing the damage it does to anything else. The only way I know to really implement this case with nice semantics is to use icky closures. Otherwise, the only alternative is to require explicit invalidate/validate calls and hope that any return statements within the part of the code where the resource is invalid are preceded by calls to validate.
Maybe some helper function that let you write code similar to using:
void UsingAndLog<T>(Func<T> creator, Action<T> action) where T:IDisposabe
{
T item = creator();
try
{
action(item);
}
finally
{
try { item.Dispose();}
catch(Exception ex)
{
// Log/pick which one to throw.
}
}
}
UsingAndLog(() => new FileStream(...), item =>
{
//code that you'd write inside using
item.Write(...);
});
Note that I'd probably not go this route and just let exceptions from Dispose to overwrite my exceptions from code inside normal using. If library throws from Dispose against strong recommendations not to do so there is a very good chance that it is not the only issue and usefulness of such library need to be reconsidered.

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!

Will code in a Finally statement fire if I return a value in a Try block?

I'm reviewing some code for a friend and say that he was using a return statement inside of a try-finally block. Does the code in the Finally section still fire even though the rest of the try block doesn't?
Example:
public bool someMethod()
{
try
{
return true;
throw new Exception("test"); // doesn't seem to get executed
}
finally
{
//code in question
}
}
Simple answer: Yes.
Normally, yes. The finally section is guaranteed to execute whatever happens including exceptions or return statement. An exception to this rule is an asynchronous exception happening on the thread (OutOfMemoryException, StackOverflowException).
To learn more about async exceptions and reliable code in that situations, read about constrained execution regions.
Here's a little test:
class Class1
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("before");
Console.WriteLine(test());
Console.WriteLine("after");
}
static string test()
{
try
{
return "return";
}
finally
{
Console.WriteLine("finally");
}
}
}
The result is:
before
finally
return
after
Quoting from MSDN
finally is used to guarantee a statement block of code executes regardless of how the preceding try block is exited.
Generally yes, the finally will run.
For the following three scenarios, the finally will ALWAYS run:
No exceptions occur
Synchronous exceptions (exceptions that occur in normal program flow).
This includes CLS compliant exceptions that derive from System.Exception and non-CLS compliant exceptions, which do not derive from System.Exception. Non-CLS compliant exceptions are automatically wrapped by the RuntimeWrappedException. C# cannot throw non-CLS complaint exceptions, but languages such as C++ can. C# could be calling into code written in a language that can throw non-CLS compliant exceptions.
Asynchronous ThreadAbortException
As of .NET 2.0, a ThreadAbortException will no longer prevent a finally from running. ThreadAbortException is now hoisted to before or after the finally. The finally will always run and will not be interrupted by a thread abort, so long as the try was actually entered before the thread abort occurred.
The following scenario, the finally will not run:
Asynchronous StackOverflowException.
As of .NET 2.0 a stack overflow will cause the process to terminate. The finally will not be run, unless a further constraint is applied to make the finally a CER (Constrained Execution Region). CERs should not be used in general user code. They should only be used where it is critical that clean-up code always run -- after all the process is shutting down on stack overflow anyway and all managed objects will therefore be cleaned-up by default. Thus, the only place a CER should be relevant is for resources that are allocated outside of the process, e.g., unmanaged handles.
Typically, unmanaged code is wrapped by some managed class before being consumed by user code. The managed wrapper class will typically make use of a SafeHandle to wrap the unmanaged handle. The SafeHandle implements a critical finalizer, and a Release method that is run in a CER to guarantee the execution of the clean-up code. For this reason, you should not see CERs littered through-out user code.
So the fact that the finally doesn't run on StackOverflowException should have no effect to user code, since the process will terminate anyway. If you have some edge case where you do need to clean-up some unmanaged resource, outside of a SafeHandle or CriticalFinalizerObject, then use a CER as follows; but please note, this is bad practice -- the unmanaged concept should be abstracted to a managed class(es) and appropriate SafeHandle(s) by design.
e.g.,
// No code can appear after this line, before the try
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This is *NOT* a CER
}
finally
{
// This is a CER; guaranteed to run, if the try was entered,
// even if a StackOverflowException occurs.
}
There's a very important exception to this which I haven't seen mentioned in any other answers, and which (after programming in C# for 18 years) I can't believe I didn't know.
If you throw or trigger an exception of any sort inside your catch block (not just weird StackOverflowExceptions and things of that ilk), and you don't have the entire try/catch/finally block inside another try/catch block, your finally block won't execute. This is easily demonstrated - and if I hadn't seen it myself, given how often I've read that it's only really weird, tiny corner-cases that can cause a finally block not to execute, I wouldn't have believed it.
static void Main(string[] args)
{
Console.WriteLine("Beginning demo of how finally clause doesn't get executed");
try
{
Console.WriteLine("Inside try but before exception.");
throw new Exception("Exception #1");
}
catch (Exception ex)
{
Console.WriteLine($"Inside catch for the exception '{ex.Message}' (before throwing another exception).");
throw;
}
finally
{
Console.WriteLine("This never gets executed, and that seems very, very wrong.");
}
Console.WriteLine("This never gets executed, but I wasn't expecting it to.");
Console.ReadLine();
}
I'm sure there's a reason for this, but it's bizarre that it's not more widely known. (It's noted here for instance, but not anywhere in this particular question.)
I realize I'm late to the party but in the scenario (differing from the OP's example) where indeed an exception is thrown MSDN states (https://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx): "If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation."
The finally block is only guaranteed to execute if some other function (such as Main) further up the call stack catches the exception. This detail is usually not a problem because all run time environments (CLR and OS) C# programs run on free most resources a process owns when it exits (file handles etc.). In some cases it may be crucial though: A database operation half underway which you want to commit resp. unwind; or some remote connection which may not be closed automatically by the OS and then blocks a server.
Yes. That is in fact that main point of a finally statement. Unless something catestrophic occurs (out of memory, computer unplugged, etc.) the finally statement should always be executed.
It will also not fire on uncaught exception and running in a thread hosted in a Windows Service
Finally is not executed when in a Thread running in a Windows Service
finally wont run in case if you are exiting from the application using
System.exit(0); as in
try
{
System.out.println("try");
System.exit(0);
}
finally
{
System.out.println("finally");
}
the result would be just :
try
99% of the scenarios it will be guaranteed that the code inside the finally block will run, however, think of this scenario: You have a thread that has a try->finally block (no catch) and you get an unhandled exception within that thread. In this case, the thread will exit and its finally block will not be executed (the application can continue to run in this case)
This scenario is pretty rare, but it's only to show that the answer is not ALWAYS "Yes", it's most of the time "Yes" and sometimes, in rare conditions, "No".
The main purpose of finally block is to execute whatever is written inside it. It should not depend upon whatever happens in try or catch.However with System.Environment.Exit(1) the application will exit without moving to next line of code.

Categories