It is not entirely true that finally will always be executed. See this answer from Haacked :
Two possibilities:
StackOverflowExceptionExecutingEngineException
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 {
An excellent source of information is the following article:
Top reliability recommendations
Dirk Vollmar Jul 09 '10 at 19:57 2010-07-09 19:57
source share