1

SafeHandle的文档说:

SafeHandle 类包含一个终结器,可确保句柄关闭并保证运行,即使在主机可能不信任 AppDomain 状态的一致性时意外 AppDomain 卸载期间也是如此。

我不确定“AppDomain”是什么意思,但我认为它应该始终运行,不是吗?

那么为什么这段代码:

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();
    }
}

吐出:

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

“Finalizing”只显示一次?

c2如果我将异常移到构造的位置下方,或者根本没有?

4

1 回答 1

3

Finalizer 线程中未处理的异常导致进程终止。如果终结器线程上发生未处理的异常,.NET 2.0 及更高版本不会继续运行终结器。这在Exceptions in Managed Threads中的“从以前版本的更改”部分中进行了说明。

受约束的执行区域通过确保在 CER 启动之前编译并准备好所有内容来保护您的代码免受由 JITer 或类型加载引起的内存不足错误。SafeHandle 是 CER 的扩展,因此只要您遵循 CER(和终结器)的规则,您就可以保证终结器不会失败,因为 JITer 无法编译终结器或其中之一的代码它调用的方法。

正如您所见,这并不能保证终结器会真正运行。

有关受约束的执行区域的更多信息

于 2013-10-22T06:16:48.840 回答