SafeHandles如何“保证”运行?

时间:2013-10-22 05:30:34

标签: c#

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

“结束”只显示一次?

如果我在下面的c2构建的位置移动Exception,那么根本不可以?

1 个答案:

答案 0 :(得分:3)

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

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

这并不能保证终结器能够实际运行,正如您所见。

有关Constrained Execution Regions

的更多信息