Difference between Finally, Finalize and Dispose in C#

In this article, We will learn about using the finally, finalize and dispose method, as well as what makes them different. In C# the major difference between finally, finalize, and dispose is that finally is the block that is executed on exception handling whether an exception occurred or not. Therefore, it allows you the option to do operations or cleanup after everything else in the try-catch-finally-block. So it is with the method-level cleanup.

Finally and finalize are different things and finalize is not a part of exception handling. In C#, the finalize is used to destroy objects of class when the scope of an object ends.
When the garbage collector collects instances of the class, the finalize is the destructor who does any cleanup. The instance-level cleanup is done by the Finalize.

Whereas Dispose is an object method in C# that is used to release and reset unmanaged resources including file handles and database connections as well as to execute code necessary for memory cleanup. By releasing unmanageable objects and limited resources, such as Graphics Device Interface (GDI) handles used in programs with limited Windows space, dispose enhances performance and optimizes memory.


Finally keyword in C# :


In the context of C#, the Finally block is a set of statements that are always carried out, regardless of any unexpected occurrences or exceptions that may take place while a program is running. It is an optional addition to the "try/catch" block that ensures the execution of any code that must be run before leaving the "try" block, whether the application is successful or unsuccessful in running.

An exception in programming can occasionally result in an error that terminates the active method. That approach, however, might have started a network or file that needs to be closed. Therefore, C# offers a specific keyword called the Finally keyword to address these kinds of issues. In C#, it is a reserved keyword. Finally block can be used to output “cleanup” code such as closing a file, closing a connection, etc. After the try-and-catch blocks of code, the Finally block of code is executed with the primary goal of releasing the resources that were used.

Given below is the example of the finally block syntax.

Syntax :

try

{

  // do something

}

finally

{

  // do something

}





try


{

  // Do something


}

  // this can be optional


catch


{

  // Do something


}


finally


{

  // Do something


}


You can see that there are two different ways to write the finally

 block in C#. These are what they are:


  • Try and Finally : Because exceptions are not handled in this situation, abnormal termination will still occur even if a runtime error occurs, and the finally blocks will be executed.

  • Try, Catch, and Finally: In this instance, the exception will be handled, and all efforts will be made to prevent the abnormal termination as well as the execution of the statements included within the "finally" block.

Below is another example of finally block with try and catch to get the proper usage and idea by the following code.

Example :

using System;


namespace ExceptionHandlingDemo

{

    internal class Program

    {

        static void Main(string[] args)

        {

            try

            {

                int x = 100;

                int y = 50; // suppose if we will put the value of y = 0; then we will get exception.

                int z = x / y;

                Console.WriteLine(z);

            }

            catch(DivideByZeroException ex)

            {

                Console.WriteLine(ex.Message);

            }

            finally

            {

                Console.WriteLine("Finally block executed..!");

            }


            Console.ReadLine();

        }

    }

}


Output :


2


Finally
block executed..!



Why we should use C# finally keyword :


  • Finally block can be used to output “cleanup” code such as closing a file, closing a connection, etc.

  • Whether or not an exception is thrown, the finally keyword is used as a block to execute a certain collection of statements. For instance, whether an exception is raised or not, if a file is opened, it must be closed.

  • C# finally block is always executed whether an exception occurs or not.

  • C# finally block is always executed whether an exception is handled or not.

  • C# finally block is a block that is used to execute important code such as closing connection, stream, etc.

  • C# finally block follows try or catch block. For each try block, there can be zero catch blocks, but only one finally block.




Finalize Method in C# :


Finalize method also called destructor to the class. The procedure finalize cannot be explicitly called in the code. When an object becomes unavailable, only the garbage collector can make the Finalize call. The finalize method may only be used after declaring a destructor; it cannot be used directly. How to declare a destructor is shown in the following class. If you must implement the Finalize method, it is advised that you do so in conjunction with the Dispose method. Destructor is converted to Finalize method after compilation.

It is the perfect location to clean implicitly managed unmanaged resources, such as COM Component Object Model objects, database connections, and file handlers that have been referenced by classes. Only once during the object's lifetime does finalize get called implicitly, and that is when the object is declared out of scope.

Writing cleanup code in the destructor or Finalize results in a double GC visit, which has a multiplicative effect on performance. Use it, then, only if necessary to clear up unmanaged code. Implement IDisposable.Dispose whenever you use the Finalize method with GC. SuppressFinalize.

The base class's Finalize function is called implicitly when you use the destructor to release resources. A destructor and a finalize are interchangeable concepts.

Here is an illustration of a destructor declaration for the class Employee:

Example:

class Employee

{

    ~Employee()  // destructor

    {

        // cleanup statements...

    }

} 


The base class's Finalize method is called implicitly by the Employee class's destructor.

As a result, the destructor code from earlier is implicitly transformed into the code below.

Example:

protected override void Finalize()

{

    try

    {

        // Necessary cleanup code...

    }

    finally

    {

        base.Finalize();

    }

}


Example:

public
class
DemoClassIDisposable {  

  

    //Construcotr   

    public
DemoClass() {  

        //Initialization:   

    }  

  

    //Destructor also called Finalize   

    ~DemoClass() {  

        this.Dispose();  

    }  

  

    public
void
Dispose() {  

        //write code to release unmanaged resource.   

    }  

}  




It is generally advised to wait to use the Finalize approach unless it is essential. Implementing the Dispose technique and cleaning up any uncontrolled areas as soon as the processing is through should always come first.

The example that follows shows that when an object that overrides Finalize is destroyed, the Finalize method is called. To release unmanaged resources that the object has in reserve, the Finalize function would be overridden. -Also, observe that the destructor is offered by the C# example rather than being replaced by the Finalize method.

Below is another example of Finalize method to get the proper concept by the following code.

Example:


using System;

using System.Diagnostics;


public class ExampleClass

{

   Stopwatch sw;


   public ExampleClass()

   {

      sw = Stopwatch.StartNew();

      Console.WriteLine("Instantiated object");

   }


   public void ShowDuration()

   {

      Console.WriteLine("This instance of {0} has been in existence for {1}",

                        this, sw.Elapsed);

   }


   ~ExampleClass()

   {

      Console.WriteLine("Finalizing object");

      sw.Stop();

      Console.WriteLine("This instance of {0} has been in existence for {1}",

                        this, sw.Elapsed);

   }

}


public class Demo

{

   public static void Main()

   {

      ExampleClass ex = new ExampleClass();

      ex.ShowDuration();

   }

}



// The example displays output like the following:

//    Instantiated object

//    This instance of ExampleClass has been in existence for 00:00:00.0011060

//    Finalizing object

//    This instance of ExampleClass has been in existence for 00:00:00.0036294



When we should use Finalize Method :


  • Finalize method 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.

  • Only unmanaged resources should be released by Finalize.

  • Never call virtual methods from finalize or allocate memory in Finalize.

  • A Finalize execution on any specific instance is not guaranteed by the framework.

  • Finalize is responsible for the cleaning of the unmanaged resources like Files, DB connections, COM, etc. held by the object before the object is destroyed.

  • Avoid making empty destructors. In other words, unless your class has to dispose of unmanaged resources, you should never explicitly specify a destructor. If you do, it should do some action. Later, if cleaning up unmanaged resources in the destructor is no longer necessary, remove it entirely.



Dispose Method in C# :


In contrast to Finalize's implicit memory cleanup, the Dispose method gives explicit memory cleanup control and manages the lifespan of object memory instances. Even when there are additional memory object instances present, Dispose may still be used.

Because (GC) garbage collector has its mechanism to free up memory, cleaning up resources through Finalize or Destructor is nondeterministic. The CLR provides a means to achieve deterministic resource cleanup using the IDisposable interface's Dispose method, which enables explicit execution by the object.

The primary and crucial job of the garbage collector (GC) in.NET is memory management, allowing programmers to concentrate on the functionality of their applications. Memory (objects) that are not being used by the program must be released via the garbage collector. However, the GC has the restriction that it can only release or reclaim memory that is being used by managed resources. There are a few resources like file handlers, window handlers, network sockets, database connections, etc. that the GC cannot release because it lacks the knowledge about how to claim memory from those resources.

The IDisposable interface consists of only one Dispose method with no arguments. Mentioned below is an example of Dispose method.


Example:

using System;

using System.ComponentModel;


// The following example demonstrates how to create

// a resource class that implements the IDisposable interface

// and the IDisposable.Dispose method.


public class DisposeExample

{

    // A base class that implements IDisposable.

    // By implementing IDisposable, you are announcing that

    // instances of this type allocate scarce resources.

    public class MyResource: IDisposable

    {

        // Pointer to an external unmanaged resource.

        private IntPtr handle;

        // Other managed resource this class uses.

        private Component component = new Component();

        // Track whether Dispose has been called.

        private bool disposed = false;


        // The class constructor.

        public MyResource(IntPtr handle)

        {

            this.handle = handle;

      
}


        // Implement IDisposable.

        // Do not make this method virtual.

        // A derived class should not be able to override this method.

        public void Dispose()

        {

            Dispose(disposing: true);

            // This object will be cleaned up by the Dispose method.

            // Therefore, you should call GC.SuppressFinalize to

            // take this object off the finalization queue

            // and prevent finalization code for this object

            // from executing a second time.

            GC.SuppressFinalize(this);

        }


        // Dispose(bool disposing) executes in two distinct scenarios.

        // If disposing equals true, the method has been called directly

        // or indirectly by a user's code. Managed and unmanaged resources

        // can be disposed.

        // If disposing equals false, the method has been called by the

        // runtime from inside the finalize and you should not reference

        // other objects. Only unmanaged resources can be disposed.

        protected virtual void Dispose(bool disposing)

        {

            // Check to see if Dispose has already been called.

            if(!this.disposed)

            {

                // If disposing equals true, dispose all managed

                // and unmanaged resources.

                if(disposing)

                {

                    // Dispose managed resources.

                    component.Dispose();

                }


                // Call the appropriate methods to clean up

                // unmanaged resources here.

                // If disposing is false,

                // only the following code is executed.

                CloseHandle(handle);

                handle = IntPtr.Zero;


                // Note disposing has been done.

                disposed = true;

            }

        }


        // Use interop to call the method necessary

        // to clean up the unmanaged resource.

        [System.Runtime.InteropServices.DllImport("Kernel32")]

        private extern static Boolean CloseHandle(IntPtr handle);


        // Use C# finalize syntax for finalization code.

        // This finalize will run only if the Dispose method

        // does not get called.

        // It gives your base class the opportunity to finalize.

        // Do not provide finalize in types derived from this class.

        ~MyResource()

        {

            // Do not re-create Dispose clean-up code here.

            // Calling Dispose(disposing: false) is optimal in terms of

            // readability and maintainability.

            Dispose(disposing: false);

        }

    }

    public static void Main()

    {

        // Insert code here to create

        // and use the MyResource object.

    }

}




When we should use Dispose Method in C# :


  • used for unmanaged resources that need to be released right once after use.

  • The Finalize method should be used if Dispose is not called.

·        Implement IDisposable on every type that has a finalize.

·        Exceptions should be carefully handled if the Dispose method is invoked more than once. If resources are Disposed, any instance method may throw the ObjectDisposedException.

·        Dispose method is recommended only for the management of native resource objects and Component Object Model (COM) objects exposed to the .NET Framework.

·        Allow Dispose to be called multiple times without raising errors.

·        Suppress later calls to the finalize from within the Dispose method using the GC.SuppressFinalize method.


Difference between Finalize and Dispose Method:



  • The primary distinction between dispose() and finalize() is that finalize() is called by the garbage collector immediately before an object is destroyed, but dispose() must be manually called by the user.

  • While the method finalize() is defined inside the class object, the dispose() function is defined inside the interface IDisposable.

  • Before an object is destroyed, Finalize is in charge of cleaning up any unmanaged resources it may have, such as Files, DB connections, COM, etc. Whereas Dispose can instantly release unmanaged resources like files, DB connections, COM, etc.

  • Finalize can only be called by the garbage collector and cannot be by the user. Whereas in Dispose the users must explicitly invoke the Dispose method.

  • While the garbage collector calls the method finalize when it discovers that an object hasn't been accessed for a while, the method Dispose could be called at any moment.

  • The function finalize() is slower and does not immediately release the resources that the object is holding. Where The function finalize() is slower and does not immediately release the resources that the object is holding. 


Conclusion :


Finally is the block that is executed on exception handling whether an exception occurred or not. Where The primary distinction between dispose() and finalize() is that finalize() is called by the garbage collector immediately before an object is destroyed, but Dispose() must be manually called by the user.

The Finally block is a set of statements that are always carried out, regardless of any unexpected occurrences or exceptions that may take place while a program is running. Where Finalize can only be called by the garbage collector and cannot be by the user. Whereas in Dispose the users must explicitly invoke the Dispose method.

I hope you found this post to be interesting and helpful. Please add your opinions and suggestions to the discussion below.




Share This Post

Linkedin
Fb Share
Twitter Share
Reddit Share

Support Me

Buy Me A Coffee