During execution, object.Finalize is automatically called after an object becomes inaccessible, unless the object has been exempted from finalization by a call to GC.SuppressFinalize(object). During shutdown of an application domain, object.Finalize is automatically called on objects that are not exempt from finalization, even those that are still accessible. object.Finalize is automatically called only once on a given instance, unless the object is re-registered using a mechanism such as GC.ReRegisterForFinalize(object) and GC.SuppressFinalize(object) has not been subsequently called.
Conforming implementations of the CLI are required to make every effort to ensure that for every object that has not been exempted from finalization, the object.Finalize method is called after the object becomes inaccessible. However, there might be some circumstances under which Finalize is not called. Conforming CLI implementations are required to explicitly specify the conditions under which Finalize is not guaranteed to be called.
In addition to GC.ReRegisterForFinalize(object) and GC.SuppressFinalize(object), conforming implementations of the CLI are allowed to provide other mechanisms that affect the behavior of object.Finalize . Any mechanisms provided are required to be specified by the CLI implementation.
The order in which the Finalize methods of two objects are run is unspecified, even if one object refers to the other.
The thread on which Finalize is run is unspecified.
The object.Finalize implementation does nothing.
A type should implement Finalize when it uses unmanaged resources such as file handles or database connections that must be released when the managed object that uses them is reclaimed. Because Finalize methods can be invoked in any order (including from multiple threads), synchronization can be necessary if the Finalize method can interact with other objects, whether accessible or not. Furthermore, since the order in which Finalize is called is unspecified, implementers of Finalize (or of destructors implemented through overriding Finalize) must take care to correctly handle references to other objects, as their Finalize method might already have been invoked. In general, referenced objects should not be considered valid during finalization.
See the IDisposable interface for an alternate means of disposing of resources.