我正在使用 .NET 开发一个相当广泛的系统,其中涉及大量系统编程。大多数时候,我使用 IDisposable 模式来处理资源处置,但有时这不适用(或被错误遗漏)并且资源在 Finalize() 期间被销毁。这可能发生在 COM 互操作中,或者当析构函数调用 Dispose() 并且其中存在异常时。
基本上:当终结器可能抛出时,并不总是能够清楚地看到和处理每个场景。当它发生时,应用程序肯定会崩溃。
我特别关注这类问题的原因是终结器不是由创建或使用对象的线程调用的,因此将异常与对象所在的上下文联系起来几乎是不可能的任务创建。您得到的只是一些通用的 GC 线程。
那么,现在向公众提问:如果您解决了这些问题,您将如何控制它们?标记对象?使用允许跟踪这些问题的第 3 方工具?
此外:是否有可能触发某种全局“Finalizer throw”事件,以至少记录这个问题已经发生?
EDIT1:非常感谢所有提交宝贵意见的人,我想我现在更清楚需要做什么了。我真正想从这次讨论中得到的最后一件事是,如果有人知道在终结器中触发异常代码的方法(即使应用程序崩溃仍然不可避免),这样我至少可以记录它,而不必修改每个的析构函数类。
请您参考如下方法:
您的问题基于一个有点错误的前提,即不可能处理终结器可能抛出的每种情况。这正是您需要在这里实现的目标。终结期间发生的异常将终止进程。除非异常确实是致命的,在这种情况下会让程序崩溃,否则您应该以不会导致程序崩溃的方式处理此异常。
Finalizer throw 几乎和 C++ destructors throw 一样糟糕。 IDisposable 的大多数实现都为主动 (IDisposable.Dispose()) 和被动(终结器线程)处置操作调用相同的方法。如果 Finalizer 版本正在抛出,那么事件处置也可能会抛出。这很像 C++ 析构函数抛出,在某些情况下会阻止嵌套资源被正确处理。
不允许异常从终结器传播,除非它们对您的应用程序确实是致命的。