如何与托管资源一起使用Finalize? [英] How to use Finalize with managed resources?

查看:94
本文介绍了如何与托管资源一起使用Finalize?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直到最后确定了类 B 的实例之后,我才100%不清楚如何定义类 A 的存在。

I'm not 100% clear on how an instance of class A can be defined to exist until after the last instance of class B is finalized.

或者换句话说,我希望所有 B 内部的 A 中调用close& dispose方法B 最终定稿...并且为此发生在之前 A 本身定稿。

Or in other words, I'd like all B's to call close&dispose methods in A inside the B finalisation... and for that to happen before A itself is finalized.

情况:

A。我有一个用于非托管资源的托管包装器。打个比方,我们将A称为文件系统

A. I've got a managed wrapper for an unmanaged resource. For an analogy, lets call A a file system

B。引用A的托管资源,这些托管资源又通过A包装器请求了非托管资源。

B. managed resources that refer to A, that in turn have requested an unmanaged resource via the A wrapper. For an analyogy, lets call B a file.

其他请求->我希望使用语法能很好地播放。即显式调用using处置不应处置非托管资源。该对象将存在于对象池中。

Additional request --> I'd like the using syntax to play nicely. i.e. calling the using dispose explicitly should not dispose the unmanaged resource. The object will live in an object pool. It should only be disposed when it leaves the object pool.

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]通过C Sharp 3rd Ed进行CLR。频道21. CriticalFinalizerObject。尤其是第537页在托管资源中使用终结处理

[2] CLR via C Sharp 3rd Ed. Ch. 21. CriticalFinalizerObject. Particularly pp. 537 "Using Finalization with Managed Resources"

推荐答案

通常,您无法控制终结处理顺序。但是,您可以使用 CriticalFinalizerObject来控制两阶段顺序。还请查看SafeHandle基础结构以及FileStream的工作方式。

You cannot control finalization order in general. You can control a two-phase order, though, using CriticalFinalizerObject. Also look at the SafeHandle infrastructure and how FileStream does it.

如果这还不够,您可以通过从静态类成员(例如a成员)创建对象引用来任意控制生存期。列表或字典)。仅当您释放这些引用时,终结才会发生。因此,您将创建一个对A的引用,一旦您发现对B的GCHandle变得无效,便将其清除。

If that is not enough, you can control lifetimes arbitrarily by creating object references from a static class member (e.g. a List or Dictionary). Only when you release those references finalization can occur. So you'd create a reference to A which you clear once you notice that a GCHandle to B has become invalid.

这篇关于如何与托管资源一起使用Finalize?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆