Solved

How to dispose or free resources in c#

Posted on 2012-03-14
10
312 Views
Last Modified: 2012-03-14
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?
0
Comment
Question by:XTO
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 3
10 Comments
 
LVL 40

Accepted Solution

by:
Kyle Abrahams earned 200 total points
ID: 37721477
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).
0
 

Author Comment

by:XTO
ID: 37721644
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" />
</Grid>

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:

foo.bar.xxx = null;
foo.bar = null;
foo = null;

thanks for your help.
0
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 100 total points
ID: 37721711
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.
0
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37721817
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.
0
 
LVL 40

Expert Comment

by:Kyle Abrahams
ID: 37721901
I've used it before without much issue, but if you wanted some documentation based on it:

http://blogs.msdn.com/b/ricom/archive/2004/11/29/271829.aspx


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?
0
 

Author Comment

by:XTO
ID: 37722120
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:
http://forums.silverlight.net/p/251404/629115.aspx/1?p=True&t=634673373769337322

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:
...is there another part of the implementation somewhere else?

As far as I know, there is only
PrintPageSmall.xaml.cs
PrintPageSmall.xaml

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.
0
 
LVL 40

Expert Comment

by:Kyle Abrahams
ID: 37722170
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.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37722376
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: http://blogs.msdn.com/b/abhinaba/archive/2008/05/02/forcing-a-garbage-collection-is-not-a-good-idea.aspx

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.
0
 

Author Comment

by:XTO
ID: 37722448
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.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 37722570
The video link was dead for me.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question