1

I'm confuse about when and how to implement IDisposable.

I saw that its needed to implement IDIsposable only for class that holds unmanaged resources

so if i have class "A" that holds unmanged and managed resources and i implement IDisposable for the unmanaged resources including GC.SuppressFinalize(this) so how the managed resources will clean if the GC now will not call the finializer for my class?

I'll really appriciate if someone can make the IDisposable more clear for me (when and how to use)

skaffman
  • 398,947
  • 96
  • 818
  • 769
Maya
  • 989
  • 4
  • 12
  • 19
  • 2
    The post here is pretty definitive => http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface – StuartLC Dec 01 '11 at 07:36

3 Answers3

1

That is incorrect. You can implement IDispose for managed-only classes, as well. If you only have managed resources, and your client doesn't call Dispose, the resources will be freed by the garbage collector at some point. However, if you do want to free the resources earlier (for example, close a file or a databae connection), do that in your own Dispose method.

You shouldn't really bother with GC.SuppressFinalize unless you have a finalizer. And if you have a finalizer, try not to have one - it's much better not to get into that region unless you absolutely have to.

zmbq
  • 38,013
  • 14
  • 101
  • 171
  • I saw in the MSDN that the GC its much better for the managed resources. and even if i dont have finalizer explicit my class still have one (if not how the GC call finalizer?). also are file and db they not unmanged? – Maya Dec 01 '11 at 07:38
  • @Maya - the GC is better for managed resources for which you aren't consuming an expensive resource. This pretty much means only classes that take up relatively small amounts of memory. For managed classes that consume an expensive or contended resource, like a file or a thread or a network connection, even if the class is purely managed, you'll want to free your usage of that deterministically as soon as possible. – codekaizen Dec 01 '11 at 08:08
1
  • when part, very simplified: you should implement IDisposable when your class "owns" (which is not so obviuos sometimes) other IDisposable or unmanaged resources which need cleanup
  • how part:

    public class AClass : IDisposable 
    {
    public void Dispose() 
    {
        Dispose(true);
        GC.SuppressFinalize(this); 
    }
    
    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
        // Free managed objects.
        }
        // Free unmanaged objects.
    }
    
    ~AClass() 
    {
     // Simply call Dispose(false).
         Dispose (false);
    }
    

    }

Further reading:
http://www.codeproject.com/KB/dotnet/IDisposable.aspx
http://blogs.msdn.com/b/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx

clearpath
  • 916
  • 8
  • 24
0

The unique thing about the IDisposable interface is that the language actually provides a specific construct for it: the "using" block:

public void SomeMethod()
{
    using(IDisposable myDisposable = new SomeClassThatImplementsIDisposable())
    {
        //Do something with your disposable...
    }
    //And, it's out of scope here
}

This is a bit of syntactic sugar where what's actually going on is this:

public void SomeMethod()
{
    IDisposable myDisposable = new SomeClassThatImplementsIDisposable();
    try 
    {    
        //Do something with your disposable...
    }
    finally
    {
        myDisposble.Dispose();
    }
    //And, it's out of scope here
}

So, when you implement IDisposable, you're giving clients of your class a way to use it where they can ensure (for the most part) that the cleanup you intend for your class actually happens.

This is most common and critical in classes that hold unmanaged resources. For instance, if your class were holding a database connection, you wouldn't want clients to let it go out of scope without ever closing the connection, as that would be a memory leak. The IDisposable usage above also ensures that if some exception is generated, the "finally" implied by the "using()" will invoke your dispose so that you can at least clean up.

That said, there are certainly situations where you might use it for managed resources. One example that comes to mind off the top is if an instance of your class is listening to events raised by an instance of a longer lived class than yours. Without disposal, this also creates a memory leak (a common problem in .NET).

So, generally speaking, I'd use it in circumstances where it would be bad if an instance of your class went out of scope without all cleanup code being executed. Implementing IDisposable advertises to any clients of your class that there are resources that it holds that need to be disposed of properly.

Erik Dietrich
  • 6,080
  • 6
  • 26
  • 37
  • I would reserve the term "managed resources" for class objects which will perform any cleanup responsibilities if they are abandoned and their generation is garbage collected, but which will perform them sooner if Dispose'd. I would regard event subscriptions attached to long-lived publishers as unmanaged resources, since one could do any number of level-2 collections following the abandonment of an event subscriber and, if the publisher is still in scope, the subscriber will never be eligible for collection. Note that... – supercat Dec 02 '11 at 04:49
  • ...event subscriptions can easily represent an unbounded memory leak in some realistic and reasonable scenarios. For example, an IEnumerator may subscribe to a collection-changed event. If a collection is enumerated 100,000 times in its lifetime (hardly implausible), that may cause 100,000 subscriptions to be attached. Even a million enumerations would not be implausible, except that that many event subscriptions would choke the system. – supercat Dec 02 '11 at 04:52