如何使用托管资源Finalize?

时间:2012-04-15 17:27:29

标签: c# clr finalizer clr4.0

我不是100%清楚如何定义类 A 的实例,直到最后一个类 B 的最后一个实例完成后才存在。

或者换句话说,我希望所有 B B 最终确定中的 A 中调用close& dispose方法...并且之前发生 A 本身已经完成。

情景:

一个。我有一个非托管资源的托管包装器。举个类比,我们可以调用A文件系统

B中。引用A的托管资源,后者又通过A包装器请求了非托管资源。对于分析,我们称B为文件。

附加请求 - >我希望使用using语法很好地发挥。即明确调用using dispose不应该处置非托管资源。该对象将存在于对象池中。它只应在离开对象池时处理。

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] Why Finalize method not allowed to override

[2] CLR来自C Sharp 3rd Ed。 CH。 21. CriticalFinalizerObject。特别是第537页“使用管理资源最终确定”

1 个答案:

答案 0 :(得分:2)

一般情况下,您无法控制终结订单。但是,您可以使用CriticalFinalizerObject控制两阶段顺序。另请参阅SafeHandle基础结构以及FileStream的工作方式。

如果这还不够,您可以通过从静态类成员(例如List或Dictionary)创建对象引用来任意控制生命期。只有在您发布这些引用时才能进行终结。因此,当您发现GCHandle到B已变为无效时,您将创建对A的引用。