Reputation: 282995
The documentation for SafeHandle says:
The SafeHandle class contains a finalizer that ensures that the handle is closed and is guaranteed to run, even during unexpected AppDomain unloads when a host may not trust the consistency of the state of the AppDomain.
I'm not sure what the bit about "AppDomain" means, but I take away from that that it should always run, no?
So why does this code:
class Program
{
static void Main(string[] args)
{
var c1 = new C();
var c2 = new C();
}
}
class C: SafeHandleZeroOrMinusOneIsInvalid
{
public C() : base(true) {
handle = (IntPtr)1;
}
override protected bool ReleaseHandle() {
Console.WriteLine("Finalizing");
throw new Exception();
}
}
Spit out:
Finalizing
Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
at FinalizeErrorTest.C.ReleaseHandle()
at System.Runtime.InteropServices.SafeHandle.InternalFinalize()
at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
at System.Runtime.InteropServices.SafeHandle.Finalize()
With "Finalizing" only being displayed once?
Or not at all if I move the Exception below where c2
is constructed?
Upvotes: 1
Views: 217
Reputation: 1875
The unhandled exception within the Finalizer thread is causing the process to be terminated. .NET 2.0 and later do not continue to run finalizers if an unhandled exception occurs on the Finalizer thread. This is noted in Exceptions in Managed Threads, in the section "Changes from Previous Versions".
Constrained Execution Regions protect your code from out of memory errors caused by the JITer or type loading, by making sure everything is compiled and ready before the CER starts. A SafeHandle is an extension of a CER, so as long as you follow the rules for a CER (and a finalizer) you can be guaranteed that your finalizer will not fail because the JITer can't compile the code for the finalizer or one of the methods it calls.
This doesn't guarantee that the finalizer will actually run, as you've seen.
More information on Constrained Execution Regions
Upvotes: 3