It is not totally true that finally will always be executed. See this answer from Haacked:
Two possibilities:
StackOverflowException
ExecutingEngineException
The finally block will not be executed
when there's a StackOverflowException
since there's no room on the stack to
even execute any more code. It will
also not be called when there's an
ExecutingEngineException, which is
very rare.
However, these two exceptions are exception you cannot recover from, so basically your process will exit anyway.
As mentioned by Mehrdad, a reliable try/catch/finally will have to use Constrained Execution Regions (CER). An example is provided by MSDN:
[StructLayout(LayoutKind.Sequential)]
struct MyStruct
{
public IntPtr m_outputHandle;
}
sealed class MySafeHandle : SafeHandle
{
// Called by P/Invoke when returning SafeHandles
public MySafeHandle()
: base(IntPtr.Zero, true)
{
}
public MySafeHandle AllocateHandle()
{
// Allocate SafeHandle first to avoid failure later.
MySafeHandle sh = new MySafeHandle();
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
MyStruct myStruct = new MyStruct();
NativeAllocateHandle(ref myStruct);
sh.SetHandle(myStruct.m_outputHandle);
}
return sh;
}
}