开发者

When should I implement IDisposable? [duplicate]

开发者 https://www.devze.com 2022-12-22 13:53 出处:网络
This question already has answers here: Proper use of the IDisposable interface (19 answers) 开发者_StackOverflow
This question already has answers here: Proper use of the IDisposable interface (19 answers) 开发者_StackOverflow Closed 5 years ago.

What is the best practice for when to implement IDisposable?

Is the best rule of thumb to implement it if you have one managed object in the class, or does it depend if the object was created in the class or just passed in? Should I also do it for classes with no managed objects at all?


If you mean unmanaged objects then yes, you should be implementing it whenever you have one or more unmanaged resource you are handling in your class. You should also be using the pattern when you are possibly holding on to objects that are IDisposable themselves, and make sure to dispose of them when your class is disposed.

(agreed that this question has already been asked enough times as to run a small printer out of ink should they be printed...)


While everyone has mentioned (unmanaged) resources, I have another thing to add: I use it when I need to eliminate event handler hookups that would otherwise prevent a class from going out of scope and being garbage collected.

As an example, I have a service which gets injected in to a child view, that child view will subscribe to various async finished type events on the service. The owner of that child view has no idea what the concrete type is, it simply has it as an interface. The service may go out of scope at some arbitrary point in the future, and I don't want it hanging around not being GC'ed. Upon getting rid of that child view, the owner will call Dispose on it to give it the chance to unhook any event handlers. Here is a slightly contrived (and very pseudo code) example, note how the interface for the child view also implements IDisposable.

public class OwnerView {

    public OwnerView() {
        _childView = new ChildView(myServiceReference);
    }

    public void CloseChildView() {
        if (childView != null) {
            _childView.Close();
            _childView.Dispose();
        }

        _childView = null;
    }

    private IChildView _childView;
}

public class ChildView : IChildView {

    public ChildView(MyService serviceRef) {
        _serviceRef = serviceRef;
        _serviceRef.GetSettingsAsyncFinished += new EventHandler(someEventHandler);
    }

    public void IDisposable.Dispose() {
        _serviceRef -= someEventHandler;
    }

    private MyService _serviceRef;
}

public interface IChildView : IDisposable {
    void DoSomething();
    ... etc ...
}

There are far more authoritative comments about this from others on SO, like Do event handlers stop garbage collection from occuring? and Garbage collection when using anonymous delegates for event handling. You may also want to check out this codeproject article.


I think the docs are pretty clear about what IDisposable is good for.

The primary use of this interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.

It even has an example. In that example the class that implements IDisposable contains a handle. A handle needs to be freed when it no longer used. This is done in the Dispose() method. So the user of that class sees that it implements IDisposable and knows that the class needs to be explictily disposed when it is no longer needed (so the handle can be freed). It is a best practise (i.e. rule) that you should always call Dispose() on IDisosable instances when the instance is no longer needed.


You should implement IDisposable when your class holds resources that you want to release when you are finished using them.


When your class contains unmanaged objects, resources, opened files or database objects, you need to implement IDisposable.


If it has properties which also need to be disposed.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号