Finalizer Method

These are associated with nondeterministic (not at any specific time) destruction of objects
You should avoid using one if at all possible.
In C# it is possible to implicitly overload Object.Finalize by using the tilde notation
The time and order of execution of a finalizer cannot be predicted or pre-determined
These run just before the garbage collector runs

class MyObject 

   ~MyObject()
   {
   }
}

There are very few situations where one of these is necessary
You should really only implement a finalizer if your object contains an unmanaged resource


It is good practice to include a Finalizer (that just calls the Dispose method) incase the Dispose method is not explicitly called.


If your class manages resources you should implement IDisposable
If your class creates any unmanaged resources you should implement IDisposable and also add a Finalizer.


Managed memory is automatically released by the garbage collector and does not need to be explicitly released.
Any unmanaged memory or resources however still need to be explicitly released.
System.Object declares a virtual method Finalize (or finalizer) that is called by the garbage collector before the memory is reclaimed.
This method can be overridden to release any unmanaged memory or resources.


Therefore relaying soley on a finalizer might not be appropriate in situations where it is important to reclaim the memory and resources as soon as possible.
The IDisposable interface provides a standard way of working with the Finalize method and can also be used for managed resources as well.



Dispose Method

These are associated with deterministic (at a very specific time) destruction of objects
You should implement the Interfaces > IDisposable interface and provide an additional Dispose method.
The C# compiler will not automatically call the Dispose method when the object goes out of scope
You must explicitley call the Dispose method.
Never use object references in a Dispose method.

class MyObject : IDisposable 
   MyObject()
   {
   }
  
   protected void Dispose()
   {
      Dispose(true);
      GC.SuppressFianlize(this);
   }
}

bool disposed = false;
protected virtual void Dispose(bool disposing)
{
    if (disposed == true)
    {
        return;
    }
    if (disposing == true)
    {
        //free any managed objects
    }

    //free any unmanaged objects
    disposed = true;
}


The reason for this is because .NET uses automatic garbage collection.
One disadvantage with this approach is called nondeterministic finalization which basically means that you don't know exactly when an object will be removed from memory.




GC.SuppressFinalize

This method tells the CLR not to call the finalizer for the specified object
If the object does not have a finalizer, calling this method has not effect
Object that implement IDisposable can call this method to prevent the garbage collector from calling the finalizer and therefore releasing the unmanaged resources.



GC.Collect

This forces garbage collection


GC.WaitForPendingFinalizers




Comparison with VB 6.0

VB 6.0 used a technique called reference counting to manage when an object was removed from memory.
This method kept track of how many variables were pointing to the object and when the last variable was set to Nothing, the object was removed from memory.
This method was called deterministic finalization because you always knew when the object was removed from memory.
One disadvantage of using this approach was that objects were often never removed in the situation when two objects were pointing to each other (creating a circular reference).




© 2024 Better Solutions Limited. All Rights Reserved. © 2024 Better Solutions Limited TopPrevNext