views:

125

answers:

4

For too long I let the garbage collector do its magic, removing all responsibilities from my self.

Sadly it never turned into an issue... So I never gave a second thought to the subject.

Now when I think about it I don't really understand what the "dispose" function really does and how and when it should be implemented.

The same question for finalize...

And a last question... I have a class pictureManipulation : when I need to save/resize/change format ... I start a new instance of that class use its objects and... well let the garbage collection kill the instance

class student
{
   public void displayStudentPic()
   {
      PictureManipulation pm = new PictureManipulation();
      this.studentPic = pm.loadStudentImage(id); 
   }
}

Class Test
{
  student a = new Student();
  a.displayStudentPic();
  // Now the function execution is ended... does the pm object is dead? Will the GC will kill it?
}
+1  A: 

You need to take care about object disposal if it holds resources other than just memory held by the object itself.

For instance, if your object abstracts a file, you must be in control when the file is released, or, you will mess things up very bad: your app finished using it and it will still be locked, until GC disposes your object.

To know how to do it properly, read manuals about dispose and finalize as well as the using(){} clause.

Pavel Radzivilovsky
A: 

Garbage collector in next check, will check if each element on the managed heap is referenced somewhere if it's not it will be disposed.

By implementing the IDisposed() interface you can force the disposing process by calling student.Dispose() method wherever you want.

The whole IDisposed interface was added because former c++ programmers where missing the deterministic garbage collection ;].

If you want to force the whole garbage collection process try

System.GC.Collect();

So :

1 . You have to implement IDisposed interface if you want to force garbage collection.

2 . If there is some special logic behind your object which garbage collector can't clean up, then you have to implement it manually.

Michal Franc
GC.Collect() is only a request though - there's no guarantee that the GC will do anything.
Michael
http://stackoverflow.com/questions/233596/best-practice-for-forcing-garbage-collection-in-c here is a great answer about GC.Collect()
Michal Franc
-1: 1) The GC may never run for a given program. 2) There is a huge difference between Disposal and Finalization. 3) IDispose was added for good practical reasons, not just because some C++ developers wanted deterministic memory management. 4) Deterministic garbage collection is a oxymoron. 5) The last thing this guy needs to worry about is forcing a GC.Collect()
Binary Worrier
+3  A: 

You only need to implement the Dispose method if your type holds some unmanaged resources like DB connections, file handles, etc. or if some of the objects that are held by your type implement the IDisposable interface. Here is a few points you should consider when implementing the standard Dispose pattern:

  • if your object doesn’t hold any IDisposable objects or unmanaged resources (DB connection, for example) then you don’t need to implement the IDisposable or finalizer at all
  • if your object holds references to IDisposable objects, then call Dispose() on these objects in the Dispose method
  • if your object doesn’t hold any unmanaged resources then don’t implement a finalizer, the Garbage Collector won’t attempt to finalize your object (which has a performance hit) unless you have implemented a finalizer.
  • if your object holds unmanaged resources, clean them up in the finalizer without re-writing any of the cleanup code in the Dispose(bool) method already.
theburningmonk
+1: @Asaf: "Managed Resources" = Any Plain Old .Net object (that you may or may not have written) that doesn't have a "handle" to a file, database or other "thing" that exists outside your running program.
Binary Worrier
@Binary: I think Managed-resource == __does__ have an (indirect) handle to something.
Henk Holterman
@Henk: "Managed Resource" = Something the Garbage Collector worries about. No?
Binary Worrier
@Binary, My bes t understanding: Managed-resource == indirect/nested unmanaged resource. Bullet 2 in this answer.
Henk Holterman
@Henk: It appears I'm in the minority, there doesn't seem to be a definitive definition of "Managed Resource" out there, but the concencious seems to follow your definition. I stand corrected sir :)
Binary Worrier
+1: Now after reading Henk Holterman answer and seeing a really simple example... I can appreciate your guidelines.Thanks Asaf
Asaf
+1  A: 

Regarding your class Student

Do I need a Dispose() ?

Assuming the Picture class is IDisposbale: Yes. Because a Student object 'owns' the studentPic and hat makes it responsible for cleaning it up. A minimal implementation:

class Student : IDisposable
{
   private PictureClass studentPic;
   public void Dispose()
   {
      if (studentPic != null)
        studentPic.Dispose();
   }
   ...
}

And you now use a Student like:

void Test
{
  using (Student a = new Student())
  {
     a.displayStudentPic();    
  } // auto Dispose by using() 
}

If you can't/don't use a using(){} block, simply call a.Dispose(); when you're done with it.

But please note that the (far) better design here would be to avoid keeping a picture object inside your Student object. That sets off a whole chain of responsibilities.

Do I need a Finalizer?

No. Because when a Student object is being collected, its studentPic object is guaranteed to be collected in the same run. A Finalizer (destructor) would be pointless but still expensive.

Henk Holterman
Great answer to help take the first step for understanding... theory is very important but I always find the first step the hardest :)
Asaf