Finalize vs Dispose

Solution 1:

The finalizer method is called when your object is garbage collected and you have no guarantee when this will happen (you can force it, but it will hurt performance).

The Dispose method on the other hand is meant to be called by the code that created your class so that you can clean up and release any resources you have acquired (unmanaged data, database connections, file handles, etc) the moment the code is done with your object.

The standard practice is to implement IDisposable and Dispose so that you can use your object in a using statment. Such as using(var foo = new MyObject()) { }. And in your finalizer, you call Dispose, just in case the calling code forgot to dispose of you.

Solution 2:

Others have already covered the difference between Dispose and Finalize (btw the Finalize method is still called a destructor in the language specification), so I'll just add a little about the scenarios where the Finalize method comes in handy.

Some types encapsulate disposable resources in a manner where it is easy to use and dispose of them in a single action. The general usage is often like this: open, read or write, close (Dispose). It fits very well with the using construct.

Others are a bit more difficult. WaitEventHandles for instances are not used like this as they are used to signal from one thread to another. The question then becomes who should call Dispose on these? As a safeguard types like these implement a Finalize method, which makes sure resources are disposed when the instance is no longer referenced by the application.

Solution 3:

Finalize is the backstop method, called by the garbage collector when it reclaims an object. Dispose is the "deterministic cleanup" method, called by applications to release valuable native resources (window handles, database connections, etc.) when they are no longer needed, rather than leaving them held indefinitely until the GC gets round to the object.

As the user of an object, you always use Dispose. Finalize is for the GC.

As the implementer of a class, if you hold managed resources that ought to be disposed, you implement Dispose. If you hold native resources, you implement both Dispose and Finalize, and both call a common method that releases the native resources. These idioms are typically combined through a private Dispose(bool disposing) method, which Dispose calls with true, and Finalize calls with false. This method always frees native resources, then checks the disposing parameter, and if it is true it disposes managed resources and calls GC.SuppressFinalize.

Solution 4:

Finalize gets called by the GC when this object is no longer in use.

Dispose is just a normal method which the user of this class can call to release any resources.

If user forgot to call Dispose and if the class have Finalize implemented then GC will make sure it gets called.

Solution 5:

Finalize

  • Finalizers should always be protected, not public or private so that the method cannot be called from the application's code directly and at the same time, it can make a call to the base.Finalize method
  • Finalizers should release unmanaged resources only.
  • The framework does not guarantee that a finalizer will execute at all on any given instance.
  • Never allocate memory in finalizers or call virtual methods from finalizers.
  • Avoid synchronization and raising unhandled exceptions in the finalizers.
  • The execution order of finalizers is non-deterministic—in other words, you can't rely on another object still being available within your finalizer.
  • Do not define finalizers on value types.
  • Don't create empty destructors. In other words, you should never explicitly define a destructor unless your class needs to clean up unmanaged resources and if you do define one, it should do some work. If, later, you no longer need to clean up unmanaged resources in the destructor, remove it altogether.

Dispose

  • Implement IDisposable on every type that has a finalizer
  • Ensure that an object is made unusable after making a call to the Dispose method. In other words, avoid using an object after the Dispose method has been called on it.
  • Call Dispose on all IDisposable types once you are done with them
  • Allow Dispose to be called multiple times without raising errors.
  • Suppress later calls to the finalizer from within the Dispose method using the GC.SuppressFinalize method
  • Avoid creating disposable value types
  • Avoid throwing exceptions from within Dispose methods

Dispose/Finalized Pattern

  • Microsoft recommends that you implement both Dispose and Finalize when working with unmanaged resources. 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.
  • Cleanup the unmanaged resources in the Finalize method as well as Dispose method. Additionally call the Dispose method for any .NET objects that you have as components inside that class(having unmanaged resources as their member) from the Dispose method.