Finalize() and Dispose()
October 6, 2012 1 Comment
C# provides special methods that are used to release the instance of a class from memory, Finalize() and Dispose().
Finalize()
- The Finalize method is used to perform cleanup operations on unmanaged resources held by the current object before the current object is destroyed.
- In C# destructor are converted to finalize method by C# compiler.
- The scope of the Object.Finalize method is protected.
- The Finalize() destructor is called after the last reference to an object is released from the memory.
- It is automatically called by garbage collector to release resource.
- The exact time when the finalizer executes during garbage collection is undefined.
Illustrate by an example
Create a class FinalizeImplement which has a destructor ~FinalizeImplement()
using System; using System.Diagnostics; namespace CSharp { class FinalizeImplement { Stopwatch sw; public FinalizeImplement() { 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); } ~FinalizeImplement() { Console.WriteLine("Finalizing object"); sw.Stop(); Console.WriteLine("This instance of {0} has been in existence for {1}", this, sw.Elapsed); Console.ReadLine(); } } }
Create a program in which implemented finalize
namespace CSharp { class Program { static void Main(string[] args) { FinalizeImplement objFinalize = new FinalizeImplement(); objFinalize.ShowDuration(); } } }
OUTPUT
Dispose()
- The Dispose() method is called to release a resource, such as a database connection, as soon as the object using such a resources is no longer in use.
- It is not automatically and you must explicitly call it from client application when an object is no longer needed.
- The IDisposable interface contains the Dispose() method.
- A Dispose method should call the GC.SuppressFinalize method for the object it is disposing. If the object is currently on the finalization queue, GC.SuppressFinalize prevents its Finalize method from being called.
- Use this method to close or release unmanaged resources such as files, streams, and handles held by an instance of the class that implements this interface.
Illustrate by an example
Create a class DisposableResource. This class shows how to use a disposable resource. The resource is first initialized and passed to the constructor, but it could also be initialized in the constructor. The lifetime of the resource does not exceed the lifetime of this instance.This type does not need a finalizer because it does not directly create a native resource like a file handle or memory in the unmanaged heap.
using System; using System.IO; namespace DisposeExample { public class DisposableResource : IDisposable { private Stream mResource; private bool mDisposed; // The stream passed to the constructor must be readable and not null. public DisposableResource(Stream stream) { if (stream == null) { throw new ArgumentNullException("Stream in null."); } if (!stream.CanRead) { throw new ArgumentException("Stream must be readable."); } mResource = stream; mDisposed = false; } // Demonstrates using the resource. It must not be already disposed. public void GetResourceSize() { if (mDisposed) { throw new ObjectDisposedException("Resource was disposed."); } // Show the number of bytes. int numBytes = (int)mResource.Length; Console.WriteLine("Number of bytes: {0}", numBytes.ToString()); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } //Disposing resource if its not already dispose protected virtual void Dispose(bool disposing) { // If you need thread safety, use a lock around these operations, as well as in your methods that use the resource. if (!mDisposed) { if (disposing) { if (mResource != null) { mResource.Dispose(); } Console.WriteLine("Object disposed."); } // Indicate that the instance has been disposed. mResource = null; mDisposed = true; } } } }
Create a program in which implemented dispose
using System; using System.IO; namespace DisposeExample { class Program { static void Main(string[] args) { try { // Initialize a Stream resource to pass to the DisposableResource class. Console.Write("Enter filename with full path: "); string fileSpecification = Console.ReadLine(); FileStream fStream = File.OpenRead(fileSpecification); DisposableResource objDisposableResource = new DisposableResource(fStream); // Use the resource. objDisposableResource.GetResourceSize(); // Dispose the resource. objDisposableResource.Dispose(); Console.Read(); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); } } } }