The garbage collector does not know how to free unmanaged resources (such as file handles, network connections, and database connections). When defining a class, you can use two mechanisms to automate the freeing of unmanaged resources
Declaring a destructor (or finalizer) as a member of your class
Implementing the System.IDisposable interface in your class
Destructors
Destructors are called before an object is destroyed by the garbage collector. When you define a destructor in C#, what is emitted into the assembly by the compiler is actually a method called Finalize().
class MyClass
{
~MyClass()
{
// destructor implementation
}
}
The following example shows the C# code equivalent to the IL that the compiler would generate for the~MyClass destructor:
protected override void Finalize()
{
try
{
// destructor implementation
}
finally
{
base.Finalize();
}
}
C# destructors are non deterministic
When a C++ object is destroyed, its destructor runs immediately. Here it depends on GC. Another problem with C# destructors is that the implementation of a destructor delays the final removal of an object from memory.Objects that do not have a destructor get removed from memory in one pass of the garbage collector, but objects that have destructors require two passes to be destroyed:
The first one calls the destructor without removing the object, and the second actually deletes the object.
The IDisposable Interface
In C#, the recommended alternative to using a destructor is using the System.IDisposable interface
The implementation of Dispose() should explicitly free all unmanaged resources used directly by an object
Suppose you have a class named ResourceGobbler, which relies on the use of some external resource and implements IDisposable
ResourceGobbler theInstance = new ResourceGobbler();
// do your processing
theInstance.Dispose();
Unfortunately, this code fails to free the resources consumed by theInstance if an exception occurs during processing
ResourceGobbler theInstance = null;
try
{
theInstance = new ResourceGobbler();
// do your processing
}
finally
{
if (theInstance != null) theInstance.Dispose();
}
C# offers a syntax that you can use to guarantee that Dispose() will automatically be called against an object that implements
IDisposable when its reference goes out of scope
using (ResourceGobbler theInstance = new ResourceGobbler())
{
// do your processing
}
variable to be scoped
when that variable goes out of scope, its Dispose() method will be called automatically, even if an exception occurs.
Implementing IDisposable and a Destructor
The execution of a destructor is enforced by the runtime but is nondeterministic and places an unacceptable overhead on the runtime because of the way garbage collection works.
The IDisposable interface provides a mechanism that allows users of a class to control when resources are freed, but requires discipline to ensure that Dispose() is called.
Regards,
Praveen KVC
5 February 2010
Thursday, February 11, 2010
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment