locked
difference dispose finalize RRS feed

Answers

  • The GAC stores assemblies, it has nothing to do with garbage collection.  You cannot call the Finalize() method explicitly, only the finalizer thread can do that.  You'd call Dispose().  Dispose() should release the resource and call GC.SuppressFinalize() because the finalizer isn't needed anymore.  Assuming it has a finalizer.

    Yes, you should call Dispose() if you can.  It is not always practical to do so since you don't always know what other references to the object may exist.  The object is dead once it is disposed.

    Remind yourself again that writing a finalizer is *very* unusual.  You are probably doing something wrong when you contemplate it.  All of this is very well described in Jeffrey Richter's book "CLR via C#".  Highly recommended.

    Hans Passant.
    • Proposed as answer by Figo Fei Monday, August 24, 2009 9:44 AM
    • Marked as answer by Figo Fei Friday, August 28, 2009 7:24 AM
    Saturday, August 22, 2009 1:41 PM
  • Hans is correct on all counts, except one minor issue; the Dispose method and Finaliser should do slightly different things in detail (same thing in principle), in that the finaliser should only release unmanaged resources directly owned by a class, you should not dispose other (child) managed objects from the finaliser as the GC either has or is about to collect them too and making calls to them can cause problems (or so I've read). So;

    1. Dispose (should) disposes all internal resources, including managed objects owned by the object being disposed and unmanaged resources owned directly by that object.

    2. The finaliser (which is only called by the GC, and in theory only if that class has not already been disposed because you should call GC.SuppressFinalise(this) from the Dispose method) will only dispose unmanaged resources owned directly by the class being finalised.

    You only need a finaliser if your class uses unmanaged directly, and in that case you should also implement IDisposable. Otherwise, you need to implement IDisposable, if you keep class level references to any other objects that implement IDisposable.

    BTW... FxCop and Code Analysis (only available in Team Suite edition) are really good at analysing your code and alerting you to classes that should be dispoable and aren't, or objects that should be disposed in the Dispose method and aren't. They'll also tell you about other common problems implementing IDisposable, like forgetting to call GC.SupressFinalize(this) in the Dispose method.

    This link has a sample on how to implement IDisposable and a finaliser correctly, although it's not particularly well documented as a sample;

    http://msdn.microsoft.com/en-us/library/ms244737(VS.80).aspx

    Note the isDisposing boolean passed to the protected Dispose(bool) method, which tells the code whether to dispose everything (from the public Dispose() method) or just the unmanaged resources (as when called from the finaliser).

    • Proposed as answer by Figo Fei Monday, August 24, 2009 9:44 AM
    • Marked as answer by Figo Fei Friday, August 28, 2009 7:24 AM
    Sunday, August 23, 2009 1:31 AM

All replies

  • There is no real difference, they both do the same job.  If you have a finalizer, you should always implement IDisposable so that the client of your class can clean up the resources explicitly, rather than letting the finalizer thread get around to it.  That takes time.  You must also implement IDisposable if your class has any members that have a Dispose() method.  So that you can dispose them when your class object gets disposed. 

    Which is by far the more common case, having to implement your own finalizer is *very* rare.  It's the job of .NET classes to manage Windows resources that need to be finalized.  Like SafeHandle.

    Hans Passant.
    Saturday, August 22, 2009 1:23 PM
  • so what you are saying i should always call Dispose if I want to free up resources and should not rely on GAC. but then why we have option of calling finalize explicity. what happens we dispose is already called and we call finalize.


    Huzaifa Gain
    Saturday, August 22, 2009 1:27 PM
  • The GAC stores assemblies, it has nothing to do with garbage collection.  You cannot call the Finalize() method explicitly, only the finalizer thread can do that.  You'd call Dispose().  Dispose() should release the resource and call GC.SuppressFinalize() because the finalizer isn't needed anymore.  Assuming it has a finalizer.

    Yes, you should call Dispose() if you can.  It is not always practical to do so since you don't always know what other references to the object may exist.  The object is dead once it is disposed.

    Remind yourself again that writing a finalizer is *very* unusual.  You are probably doing something wrong when you contemplate it.  All of this is very well described in Jeffrey Richter's book "CLR via C#".  Highly recommended.

    Hans Passant.
    • Proposed as answer by Figo Fei Monday, August 24, 2009 9:44 AM
    • Marked as answer by Figo Fei Friday, August 28, 2009 7:24 AM
    Saturday, August 22, 2009 1:41 PM
  • to have a finalizer for my object what interface should implement
    Huzaifa Gain
    Saturday, August 22, 2009 1:44 PM
  • There's no interface, you write a destructor in C#:

      class Something {
        ~Something() {
          // finalizer, really
          //...
        }
      }

    Hans Passant.
    Saturday, August 22, 2009 1:56 PM
  • Hans is correct on all counts, except one minor issue; the Dispose method and Finaliser should do slightly different things in detail (same thing in principle), in that the finaliser should only release unmanaged resources directly owned by a class, you should not dispose other (child) managed objects from the finaliser as the GC either has or is about to collect them too and making calls to them can cause problems (or so I've read). So;

    1. Dispose (should) disposes all internal resources, including managed objects owned by the object being disposed and unmanaged resources owned directly by that object.

    2. The finaliser (which is only called by the GC, and in theory only if that class has not already been disposed because you should call GC.SuppressFinalise(this) from the Dispose method) will only dispose unmanaged resources owned directly by the class being finalised.

    You only need a finaliser if your class uses unmanaged directly, and in that case you should also implement IDisposable. Otherwise, you need to implement IDisposable, if you keep class level references to any other objects that implement IDisposable.

    BTW... FxCop and Code Analysis (only available in Team Suite edition) are really good at analysing your code and alerting you to classes that should be dispoable and aren't, or objects that should be disposed in the Dispose method and aren't. They'll also tell you about other common problems implementing IDisposable, like forgetting to call GC.SupressFinalize(this) in the Dispose method.

    This link has a sample on how to implement IDisposable and a finaliser correctly, although it's not particularly well documented as a sample;

    http://msdn.microsoft.com/en-us/library/ms244737(VS.80).aspx

    Note the isDisposing boolean passed to the protected Dispose(bool) method, which tells the code whether to dispose everything (from the public Dispose() method) or just the unmanaged resources (as when called from the finaliser).

    • Proposed as answer by Figo Fei Monday, August 24, 2009 9:44 AM
    • Marked as answer by Figo Fei Friday, August 28, 2009 7:24 AM
    Sunday, August 23, 2009 1:31 AM