How to dispose or free resources in c#

When I read tutorials on how to use the IDisposable interface, they don't explain how to free up the resources.

For example, one tutorial has this:

void Dispose(...)
    . . . 
    // Code to cleanup managed resources held by the class
    . . . 
    // Code to cleanup unmanaged resources held by the class

Open in new window

Another tutorial, for example, has this:

void Dispose(...)
    . . . 
    // Release unmanaged resources.
    . . . 
    //  Release managed resources.

Open in new window

Then when I do a search on how to release or free resources, I get tutorials that describe garbage collection and the Dispose method, but have similar comments for releasing or disposing, or cleaning up resources in the body of the Dispose() method.
It's like an infinite recursion.

So, how does one release, or dispose, or clean up managed or unmanaged resources in the body of a Dispose() method?
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kyle AbrahamsSenior .Net DeveloperCommented:
Basically you set your controls, arrays, members to null.

Finally call GC.Collect();  to force the the garbage collector to free up unused resources.  (essentially any memory still being used that is now ready to be deallocated).

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
XTOAuthor Commented:
Thank you ged325.

So, for example, I have a Silverlight application with a class that looks like this:

public partial class PrintPageSmall : ChildWindow, IDisposable
        Envelope mapExtent;    
        PrintDocument printDoc;
        Grid mapGr;

        public PrintPageSmall(MainPage mainPage)
             // constructor code

         // Code for other methods

        public void Dispose()
            mapExtent = null;    
            printDoc = null;
            mapGr = null;

Open in new window

In the Dispose method, there are 3 variables that are global to the PrintPageSmall class.
Are global variables in that class the only things that count as "resources" for the Dispose() method of that class?

Suppose in my XAML I have:

<Grid name="printGrid">
    <Button name="printButton" />

Then do I also need to have in my Dispose() method:

printGrid = null;
printButton = null;

Also, suppose the PrintDoc object had an event called PrintPage. Would I also need to do this in the Dispose() method?

printDoc.PrintPage -= printDoc_PrintPage;

Or does that happen automatically when printDoc = null ?

Also, if foo has a property called bar, and bar has a property called xxx, then would I need to do this: = null; = null;
foo = null;

thanks for your help.
käµfm³d 👽Commented:
Danger Will Robinson! DANGER!! That is horrible advice. Calling GC.Collect from a Dispose method is very bad. I can't even begin to imagine the "speediness" of your application if you did that and had something like this in your code:

for (int i = 0; i < 1000000000; i++)
    using (MyDisposableObject obj = new MyDisposableObject())
        // do something with obj

Open in new window

It is a rare occasion that you should have to invoke the GC manually. Invoking the GC manually causes a full collection, which is incurs a good bit of overhead. Aside from that, objects go through "generations" within the GC, and invoking the GC manually may in fact only be promoting an object from one generation to another, and not necessarily freeing the memory as you might think it should.
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

käµfm³d 👽Commented:
I'm going to withdraw my assertion about the GC promoting objects between generations (in a full collection). That may only occur during a partial collection. I am not confirmed on that as of present.
Kyle AbrahamsSenior .Net DeveloperCommented:
I've used it before without much issue, but if you wanted some documentation based on it:

I guess the better question is why implement IDisposable at all?  If you are dead set on it it's good practice to dispose of everything.  

Classes get set to null . . . objects (like your grid) should have their own dispose method which should be called.

The only other thing to be careful of is that's a partial class  . . . is there another part of the implementation somewhere else?
XTOAuthor Commented:
Thank you ged325 and kaufmed,

ged325 asked:
I guess the better question is why implement IDisposable at all?

The reason that I am implementing IDisposable is to attempt to solve the problem I described here:

ged325 stated:
...objects (like your grid) should have their own dispose method which should be called.

Intellisense does not show a Dispose() method for printGrid.
So, should I go ahead and set it to null?
Do I do that with everything in the XAML object tree, or just with the global variables?
How about members of those global variables?

ged325 asked: there another part of the implementation somewhere else?

As far as I know, there is only

If Visual Studio 2010 has made another partial class, then it is not showing up under the project in the Solution Explorer and is hidden.
Kyle AbrahamsSenior .Net DeveloperCommented:
Value does not fall within the expected range.

Usually happens because you're referencing something that hasn't been set yet.

If you step through do you see where it's failing?

In general if there is no dispose method then setting to null is the way to go . . . but may not resolve your original issue.  Try creating your objects as new objects and then adding those.
käµfm³d 👽Commented:
but if you wanted some documentation based on it:
From your own "documentation":

It's fair to say that most usages of GC.Collect() are a bad idea

Further, from:

What is the problem with calling GC.Collect

So why are folks against calling GC.Collect? There are multiple reasons

    There's an inherent assumption that the user knows more about when the GC is run. This cannot be true because according to CLR spec there is no standard time. See here. Since GC is plugged into the execution engine it knows best of the system state and knows when to fire. With Silver Light and other cross-plat technologies being mainstream it will become harder and harder to predict where your app is run. There's already 3 separate GCs the desktop, server and compact framework. Silver light will bring in more and your assumptions can be totally wrong.

    GC has some cost (rather large):
    GC is run by first marking all the objects and then cleaning them. So whether garbage or not the objects will be touched and it takes awful amount of time to do that. I've seen folks measure the time to do GC.Collect and figure out the time taken. This is not correct because GC.Collect fires the collection and returns immediately. Later GC goes about freezing all the threads. So GC time is way more than what collect takes and you need to monitor performance counter to figure out what is going on,

    GC could be self tuning:
    The desktop GC for example tunes itself based on historical data. Lets assume that a large collection just happened which cleaned up 100mb of data. Incidentally exactly after that a forced GC happened which resulted in no data to be cleaned up. GC learns that collection is not helping and next time when a real collection is to be fired (low memory condition) it simply backs off based on the historical data. However, if the forced GC didn't occur it'd have remembered that 100mb got cleared and would've jumped in right away.
XTOAuthor Commented:
Thank you kaufmed for that link.
It is a very interesting read.
It is fascinating to get into the deeper aspects of dot net.
I find it particularly noteworthy that the GC seems to have some sort of pseudo-artificial intelligence:
 The desktop GC for example tunes itself based on historical data.

Unfortunately, in the attempt balance the time spent doing research versus attempting to create solutions based on strategies inferred from one's current knowledge in order to meet deadlines, I don't get as much time as I would like for research and study.

Thanks again for that link.
I look forward to watching the Patrick Dussud video on dot net garbage collection when I get home tonight.
And thank you for the help on the questions I asked about dot net event handling in another thread.
The responses I read in places like Stack Overflow can sometimes be confusing.
käµfm³d 👽Commented:
The video link was dead for me.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.