Dot Net For All

How to use Dispose And Finalize in C#

Hello Friends, In this article I will talk about the garbage collection in .NET. And continue my discussion the better techniques to collect the unused objects for better memory management with C# examples. And how .NET framework treats Dispose and Finalize in C#.

Why should we use Dispose And Finalize in C#?

Garbage collector takes care of all the hard work of freeing up the managed objects in the .NET framework. And that work is taken care by CLR by running a garbage collector on  a separate thread.

The thread keeps watching the roots in the program. The roots are the objects which are still in the scope of program execution and once these objects are out of scope of program execution, they are ready for garbage collection.

That was about the managed objects. But what about the non managed objects like SQL connection objects, file handlers, http client request  obejct which are not managed by .NET framework.

We need to explicitly close or dispose the above mentioned objects.

If we  let these objects to remain in memory of the application, there would be a situation where your application would be consuming way too much memory and causing memory leaks.

How to use Dispose using IDisposable pattern

We need to implement the IDisposable pattern for the class which contains any of the unmanaged resources.

Below is a simple example of the SQLConnector class.

     public class SQLConnector : IDisposable
    {
        SqlConnection sqlConn = null;

        public SQLConnector()
        {
            sqlConn = new SqlConnection("ConnectionString");
            sqlConn.Open();
        }

        public DataSet GetData()
        {
            //Add the code to retireve some data from the DataBase
            return new DataSet();
        }

        public void PutData()
        {
            //Add the code to update the data base
        }

        public void Dispose()
        {
            if (sqlConn != null)
                sqlConn.Dispose();
        }
    }

The above class uses a SqlConnection object. This object is not managed by .NET framework hence it is very important to dispose this object when we are done with using it.

The above class is an example of the wrapper class. The class performs some operations on the SQL database.

To dispose the object I have implemented the IDisposable interface for the class. The interface provides a method named Dispose.

This is the method where we have to write all the code to dispose of the unmanaged object.

And we can create the object of the above code as shown in the below code snippet.

            using (SQLConnector conn = new SQLConnector())
            {
                conn.GetData();
            }

I am using the using keyword. The keyword can be used with the classes which implement IDisposable interface. And it will take care of calling Dispose on your behalf.

The Dispose method will be called even of there is an exception in the using block.

But when does Finalize comes to Picture

We have written a class wrapping a unmanaged resource and properly disposed it off.

But where is Finalize and why do we need it.

Finalize is like a deconstructor which will be called by .NET framework. Suppose you have a unmanaged resource as seen in the above code and you have implemented the Dispose pattern properly.

But what if the user of the class forgets to call the Dispose method. or he does not create the instance of the class in the using code block. The resource will not be disposed and it will create memory leaks.

To circumvent this  problem .NET framework provides finalizers.

Lets re write the above code again with finalize implemented.

public class SQLConnector : IDisposable
    {
        SqlConnection sqlConn = null;

        public SQLConnector()
        {
            sqlConn = new SqlConnection("ConnectionString");
            sqlConn.Open();
        }

        public DataSet GetData()
        {
            //Add the code to retireve some data from the DataBase
            return new DataSet();
        }

        public void PutData()
        {
            //Add the code to update the data base
        }

        ~SQLConnector()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Dispose any disposable fields here
                GC.SuppressFinalize(this);
            }
            ReleaseNativeResource();
        }

        private void ReleaseNativeResource()
        {
            sqlConn.Dispose();
        }
    }

What difference can you notice in the above code from the previous snippet?

We have a couple of new methods. But the finalizer is the main method I want to talk about.

Finalizer is the method which has the same name as the containing class. For example SQLConnector in our case prefixed by tilde ‘~’.

If the dispose is called by the code and not by .NET framework we suppress the finalizer for this class.

But it is not a good idea to have a finalize method for your class. I will discuss the reason for same in my next article.

Conclusion:

Many developers think that Dispose and Finalize in C# are same and they server the same purpose but that is not the case. In this article I have discussed how both of these differ in their working.

 

Top career enhancing courses you can't miss

My Learning Resource

Excel your system design interview