如何将 Finalize 与托管资源一起使用
本文关键字:资源 一起 Finalize | 更新日期: 2023-09-27 18:31:15
我不是100%清楚如何在类B的最后一个实例完成之前
定义类A的实例存在。或者换句话说,我希望所有 B 在 B 最终确定中调用 A 中的关闭和处置方法......并在 A 本身最终确定之前发生这种情况。
场景:
一个。我有一个非托管资源的托管包装器。 打个比方,我们称 A 为文件系统
B. 引用 A 的托管资源,而这些资源又通过 A 包装器请求了非托管资源。 对于分析,我们称 B 为文件。
附加请求 --> 我希望使用语法能够很好地发挥作用。 即显式调用使用处置不应释放非托管资源。 对象将位于对象池中。 仅当它离开对象池时,才应释放它。
class SomeClass() : IDisposable{
public SomeClass(){}
public ~SomeClass(){
// dispose of unmanaged here?
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
public void Dispose(bool disposing) {
if (disposing) {
// dispose managed
} else {
// dispose unmanaged?
}
}
public void Dispose() {
Dispose(true);
//GC.SuppressFinalize(this);
}
}
引用:
[1] 为什么不允许覆盖 Finalize 方法
[2] CLR via C Sharp 3rd Ed. 第21章. CriticalFinalizerObject. 特别是第537页"使用托管资源的定稿"
一般无法控制最终排序。不过,您可以使用 CriticalFinalizerObject 控制两阶段顺序。另请查看 SafeHandle 基础结构以及 FileStream 如何做到这一点。
如果这还不够,您可以通过从静态类成员(例如 List 或 Dictionary)创建对象引用来任意控制生存期。仅当您释放这些引用时,才能完成。因此,您将创建一个对 A 的引用,一旦您注意到对 B 的 GCHandle 已失效,您就会清除该引用。