How to use Finalize with managed resources?

自闭症网瘾萝莉.ら 提交于 2020-01-05 23:15:12

问题


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.

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.

The scenario:

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

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.

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);
    }

}

References:

[1] Why Finalize method not allowed to override

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


回答1:


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.

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.



来源:https://stackoverflow.com/questions/10164340/how-to-use-finalize-with-managed-resources

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!