如何“保证”安全句柄运行

本文关键字:句柄 运行 安全 保证 如何 | 更新日期: 2023-09-27 18:36:30

SafeHandle的文档说:

类包含一个终结器,

该终结器可确保句柄关闭并保证运行,即使在主机可能不信任 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的地方,则根本不会?

如何“保证”安全句柄运行

终结器线程中未处理的异常导致进程终止。 如果终结器线程上发生未经处理的异常,则 .NET 2.0 及更高版本不会继续运行终结器。这在"与以前版本的更改"一节的托管线程中的异常中进行了说明。

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

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

有关约束执行区域的详细信息