32

In this answer I found,

Cleanup the unmanaged resources in the Finalize method and the managed ones in the Dispose method, when the Dispose/Finalize pattern has been used in your code.

And later I found this nice article about finalize and dispose and got a clear idea about them. The article has the following code(Page 3), to explain the concepts:

class Test : IDisposable
{
    private bool isDisposed = false;

    ~Test()
    {
       Dispose(false);
    }

    protected void Dispose(bool disposing)
    {
       if (disposing)
       {
          // Code to dispose the managed resources of the class
       }
       // Code to dispose the un-managed resources of the class

       isDisposed = true;
    }

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

But below that, the same note (which I included in the beginning of this question) appears.

The Dispose/Finalize Pattern Microsoft recommends that you implement both Dispose and Finalize when working with unmanaged resources. The correct sequence then would be for a developer to call Dispose. The Finalize implementation would run and the resources would still be released when the object is garbage collected even if a developer neglected to call the Dispose method explicitly. Francesco Balena writes in his blog "the Dispose/Finalize pattern should be used only when your type invokes unmanaged code that allocates unmanaged resources (including unmanaged memory) and returns a handle that you must use eventually to release the resource. Both dispose and finalize must chain up to their parent objects by calling their parent's respective methods after they have disposed or finalized their own members". Simply put, cleanup the unmanaged resources in the Finalize method and the managed ones in the Dispose method, when the Dispose/Finalize pattern has been used in your code.

Now I am confused again. In the entire article and in the code sample, it is shown that unmanaged resources should be freed in Dispose(). But then what is the relevance of that comment?

Edit:

As it is confirmed that this line :

Simply put, cleanup the unmanaged resources in the Finalize method and the managed ones in the Dispose method, when the Dispose/Finalize pattern has been used in your code

is erroneous, I edited this answer.

Set
  • 47,577
  • 22
  • 132
  • 150
Sharun
  • 3,022
  • 6
  • 30
  • 59

2 Answers2

53

See its very simple.

  1. If you are dealing with unmanaged resources - Implement both Dispose and Finalize. Dispose is to be called by developers to free up the resources as soon as they see it that its no longer needed for them. If they forget to call Dispose then Framework calls the finalize in its own GC cycle (usually will take its own sweet time).
  2. If your object uses disposable objects internally - You implement Dispose() if you created and retained a reference to any object of a type which implements Dispose() and which you haven't already disposed.
  3. If neither of the above is the case (you are NOT dealing with unmanaged resources nor your object uses disposable objects internally) - Then don't do anything. Don't implement Finalize nor Dispose.

Some classic examples:

System.IO.FileStream object manages the lock/stream handles to files. So it implements both dispose and finalize. If the developer disposes it then the other program can access it right away. If he forgets to dispose it then Framework finalize it and close the handles later in its GC cycle.

System.Text.StringBuilder dose not have any unmanaged resource. So no dispose no finalize.

As far as the pattern is concerned what it means to

// Code to dispose the managed resources of the class

is that call the Dispose methods of any .NET objects that you have as components inside that class

And

// Code to dispose the un-managed resources of the class

Means to close the raw handles and pointers. Here is your updated code with examples

class Test : IDisposable
{
  private bool isDisposed = false;

  ~Test()
  {
    Dispose(false);
  }

  protected void Dispose(bool disposing)
  {
    if (!isDisposed)
    {
      if (disposing)
      {
        // Code to dispose the managed resources of the class
        internalComponent1.Dispose();
        internalComponent2.Dispose();
      }

      // Code to dispose the un-managed resources of the class
      CloseHandle(handle);
      handle = IntPtr.Zero;   

      isDisposed = true;
    }
  }

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

Here is an old question explaining it

Garogolun
  • 323
  • 2
  • 11
Guru Kara
  • 6,272
  • 3
  • 39
  • 50
  • Actually there is no cleaning up of Managed resources at all. I dont see his point in any way relevant. The max that you can do to cleanup a managed resource is to assign it to NULL. Which is totally unnecessary with such a good GC built in. – Guru Kara May 17 '13 at 05:41
  • Thats an article written in 2006, so i would not bother much about that actually. – Guru Kara May 17 '13 at 05:41
  • 8
    It's not quite so simple. You should also implement `Dispose()` if you created and retained a reference to *any* object of a type which implements `Dispose()` and which you haven't already disposed. Some types don't use unmanaged resources but they DO have things such as subscriptions to events that they must unhook in their `Dispose()` methods. You must dispose such objects EVEN THOUGH they don't use unmanaged resources, otherwise you can have a kind of memory leak. This is often particularly true of UI classes derived from `Control` or `UserControl`. – Matthew Watson May 17 '13 at 06:11
  • @MatthewWatson : I think what you meant is, I have to call the dispose() methods for such objects in the dispose() of current class. Correct me if I am wrong. – Sharun May 17 '13 at 06:19
  • @GuruKara: Now I got the idea, and am going to simply forget the line :`cleanup the unmanaged resources in the Finalize method and the managed ones in the Dispose method, when the Dispose/Finalize pattern has been used in your code.` – Sharun May 17 '13 at 06:22
  • @Sharun Yep, that's exactly what I meant! (I +1ed the answer now - it seems complete) – Matthew Watson May 17 '13 at 06:23
  • @MatthewWatson: So, do you agree with, ignoring this line as erroneous: **Simply put, cleanup the unmanaged resources in the Finalize method and the managed ones in the Dispose method, when the Dispose/Finalize pattern has been used in your code** ? (This line was the origin of my question) – Sharun May 17 '13 at 06:29
  • @Sharun Oh sorry, yes I do agree. You should also clean up the unmanaged resources in `Dispose()` and also clean them up in the `Finalize()` if `Dispose()` was never called (you need to set a flag in `Dispose()` so you know if it was called or not when you're in the `Finalize()`. This is only necessary if *that* class created the unmanaged resource though. – Matthew Watson May 17 '13 at 06:39
  • 4
    Why the Finalize method don't free managed resources? If Dipose method was never called, who will free the managed resources? – Acaz Souza Jun 24 '13 at 13:38
  • 3
    The GC will see that the resource (managed) has no pointers to it and clean it up – Guru Kara Jun 25 '13 at 03:31
  • 1
    What code will run when the **managed** resource lost the last pointer to it? Finalizer? – Brian Cannard Jun 04 '14 at 11:34
6

If a Foo has resources which will benefit from deterministic cleanup, but none that can be usefully cleaned up in a finalizer, it should implement IDisposable but should not override Finalize or have a destructor. If a class holds multiple resources, and at least one can be cleaned up in a finalizer, then each discrete resource that could be cleaned up in a finalizer should be encapsulated into its own Finalizer/destructor-equipped object (which may be defined in a protected nested class), and the class that would contain those resources should hold references to the wrapper objects. Once that is done, the outer class will fit the pattern for classes with a Dispose method but no finalizer/destructor.

supercat
  • 77,689
  • 9
  • 166
  • 211