Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When would dispose method not get called?

I was reading this article the other day and was wondering why there was a Finalizer along with the Dispose method. I read here on SO as to why you might want to add Dispose to the Finalizer. My curiousity is, when would the Finalizer be called over the Dispose method itself? Is there a code example or is it based on something happening on the system the software is running? If so, what could happen to not have the Dispose method run by the GC.

like image 322
SwDevMan81 Avatar asked Sep 10 '09 11:09

SwDevMan81


3 Answers

The purpose of the finaliser here is simply a safety precaution against memory leaks (if you happen not to call Dispose explicitly). It also means you don't have to dispose your objects if you want them to release resources when the program shutdowns, since the GC will be forced to finalise and collect all objects anyway.

As a related point, it is important to dispose the object slightly differently when doing so from the finaliser.

~MyClass()
{
    Dispose(false);
}

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected void Dispose(disposing)
{
    if (!this.disposed)
    {
        if (disposing)
        {
            // Dispose managed resources here.
        }
        // Dispose unmanaged resources here.
    }
    this.disposed = true;
}

The reason you do not want to dispose managed resources in your finaliser is that you would actually be creating strong references to them in doing so, and this could prevent the GC from doing it's job properly and collecting them. Unmanaged resources (e.g. Win32 handles and such) should always be explicitly closed/disposed, of course, since the CLR has no knowledge of them.

like image 124
Noldorin Avatar answered Oct 12 '22 01:10

Noldorin


This is mostly there to protect yourself. You cannot dictate what the end user of your class will do. By providing a finalizer in addition to a Dispose method, the GC will "Dispose" of your object, freeing your resources appropriately, even if the user forgets to call Dispose() or mis-uses your class.

like image 28
Reed Copsey Avatar answered Oct 12 '22 00:10

Reed Copsey


The Finalizer is called when the object is garbage collected. Dispose needs to be explicitly called. In the following code the finalizer will be called but the Dispose method is not.

class Foo : IDisposable
{
  public void Dispose()
  {
    Console.WriteLine("Disposed");
  }

  ~Foo()
  {
    Console.WriteLine("Finalized");
  }
}

...

public void Go()
{
  Foo foo = new Foo();
}
like image 24
Mike Minutillo Avatar answered Oct 12 '22 00:10

Mike Minutillo