Saturday, November 9, 2013

Implementing IDisposable Interface in c#

          In this article, we are going to see how to implement IDisposable interface in c#.

Purpose:      

       Application which involves getting data from external devices like Database or files like Excel, text etc need to acquire resources. These resources could be files that we want to use from external device like clustered storage drive, database etc. The important thing to remember while using these resources is to release these resources once we are done with it.

IDisposable Description:

        IDisposable is a pattern in .NET that is used to implement explicit/implicit cleanup of unmanaged resources. .NET has a garbage collector, but that is only used to manage memory, not resources like I/O (database connection, file handles, sockets,). While in C++ destructors are called deterministically when an object goes out of scope, finalizers in C# get called by the garbage collector, but we can’t determine when that will happen.

In c#, don’t depend on the garbage collector for unmanaged resources!

Example:

Let us have class implements IDispose, which is used to read text from file.

class MyIDisposableImplementation : IDisposable
    {
        private FileStream fStream = null;
        private bool isResourceDisposed = false;      

        public void PrintData()
        {
            byte[] data = new byte[fStream.Length];
            fStream.Read(data, 0, Convert.ToInt32(fStream.Length));
            Console.WriteLine("File Data: \n" + ASCIIEncoding.Default.GetString(data));
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
            Console.WriteLine("Inside Dispose Method");
        }
        protected void Dispose(bool canDispose)
        {
            if (!isResourceDisposed)
            {
                if (canDispose)
                {
                    fStream.Dispose();
                    Console.WriteLine("Resource Disposed");
                }
                isResourceDisposed = true;
            }
        }
    }

In the above example, the class MyIDisposableImplementation reads data from text file into byte and display in console application, let’s have the types of dispose pattern applied.

1. Disposing resources without using IDispose interface:

The IDisposable-interface has a single method void Dispose(). This method is used to clean up the disposable object and release the unmanaged resources it holds. To make sure that you always call it, even if an exception occurs in the code between creating the object and calling its Dispose-method, we have to use the try-finally-construct, like this:
Ex1
   try
     {
       MyIDisposableImplementation disposePattern = new MyIDisposableImplementation(filePath);
       disposePattern.PrintData();
       Console.ReadKey();
     }
   catch (Exception ex)
     {
       Console.WriteLine("Exception {0} {1}", ex.Message, ex.InnerException);
     }
   finally
     {
       disposePattern.Dispose(); //Explicitly calling Dispose method to clean up resource
     }

2. Disposing resources with IDispose interface:

if using statement is used while accuring resource, the unmanaged resources are released automatically  that is Dispose() method is called by default, when it come out of scope. Its better to used disposable pattern for UNMANAGED RESOURCE.

Ex 2:

using (disposePattern = new MyIDisposableImplementation(filePath))
     {
        disposePattern.PrintData();
     }//Dispose method will be implicitly called to clean up resource

Output:

Generic example:

       The below example make use of FileStream and StreamWriter which implements IDisposable interface by default.

using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
  using (var writer = new StreamWriter(stream, Encoding.UTF8))
  {
    foreach (string line in lines)
    {
      writer.WriteLine(line);
    }
  }
}

Project Sample:


No comments:

Post a Comment