Dispose and Finalize in C#
2011-12-14 11:05
260 查看
Introduction
This article provides an introduction to destructors in C# and reveals the non-deterministic destructor problem.It also analyzes the
IDisposable, garbage collection,
usingstatement, etc.
Destructor
The destructor is a special purpose method in a class like a constructor. The constructor is called by the runtime after creating an instance. It is meant for initialization purposes. Like that, a destructor is called by the runtime before destroying aninstance. It is meant for finalization operations.
A destructor is declared like a constructor with a prefix tilde(~) in C#. A destructor do not have access modifiers like
public,
private, etc.
public class Shape
{
~Shape() // Destructor
{
}
}
In C#, the .NET runtime automatically destroys any class instances that are no longer in reference. It does thisduring the process of garbage collection.
Using of destructors will make the application slow in performance.
Finalizers
It is important to note that the destructors are also called Finalizers because the compiler converts a C# destructor into a method namedFinalize()in the Intermediate Language (IL). The code in the destructor will be wrapped
in a
try..finallyblock inside the
Finalize()method.
Garbage Collection
This is the process of freeing up of unused memory of objects periodically. The .NET runtime does the process of garbage collection on the following conditions:When there is shortage of memory
Developer invoked the
GC.Collect()method
The garbage collection helps the developer to free up object instances.
But remember, garbage collection only destroys the managed resources, i.e. resources created inside the managed memory.
What is the Need of Destructors?
Since the runtime is managing the destruction of all objects, a question may arise: Why do we need destructors?Answer: To destroy unmanaged resources.
The unmanaged resources are those created outside the managed environment. They may include file handles, network connections, etc. These resources created should be destroyed by the class itself, because the runtime is not able to destroy them.
Therefore, we use destructors to free up the unmanaged resources. This will ensure that all the unmanaged resources created by the class will be freed in the destructor.
E.g.: Let
Channelbe a class usingunmanaged resources having a constructor and a destructor.
public class Channel
{
public Channel()
{
// Create unmanaged resource
// Lock("c:\\file.log");
}
~Channel()
{
// Destroy unmanaged resource
// Unlock("c:\\file.log");
}
}
The
Channelclass locks a file "c:\file.log" in the constructor and unlocks it in the destructor.
Here arises a problem that we cannot predict when the destructor is called. So the file remains locked until the garbage collection, even if the object instance is out of any reference.
For the above problem, we need some method to free the unmanaged resource. In .NET, there is an interface named
IDisposablefor the purpose.
IDisposable
TheIDisposableinterface contains a method
Dispose()which should be implemented by the class. So we can move freeing up of unmanaged resources to this
Dispose()method.
Again there is a problem, that a typical .NET developer not calling the
Dispose()method after the usage of class instance. In that case, we need the call to free unmanaged resources both in the destructor and in the
Dispose()method.
We can also use a
Close()method instead of implementing the
IDisposableinterface. But, enabling the
IDisposablemakes our class usable in the
using{}statement of C#.
The
usingstatement will automatically call the
Dispose()method after exiting the scope of
using. (Please refer to the sample code.)
public class Channel: IDisposable
{
public Channel()
{
// Create unmanaged resource
Lock("c:\\file.log");
}
~Channel()
{
// Destroy unmanaged resource
Unlock("c:\\file.log");
}
void IDisposable.Dispose()
{
Unlock("c:\\file.log");
}
public void Lock(string file) { }
public void Unlock(string file) { }
}
At first look, the above code solves all the problems.
But, it creates a new problem due to the non-deterministic destructors of C#.
Non-Deterministic Destructors
In C#, we do not know when the destructor is executed. It is called only during the garbage collection process and we do not know when it actually happens. This state is called non-deterministic destructors or InDeterministic destructors.The following figure illustrates the problem. Our '
Channel' class is usingsome unmanaged resources and freeing them in the
Dispose()method and also in the destructor.
There are two cases when the
Channelclass is used:
A developer creates an instance and exits without calling
Dispose()
A developer creates an instance and calls
Dispose()
Solution usingGC.SuppressFinalize(this)
We can instruct the garbage collector not to call the destructor by usingtheGC.SuppressFinalize(this)method. So, using
thisin the
Dispose()method after freeing up unmanaged resources will solve the non-deterministic
destructor problem.
The solution is given below.
Here, the
Channelclass has freed up code both in the destructor and in the
Dispose()method. And if the developer calls the
Dispose()method, the unmanaged resources will be freed and the destructor will be disabled
by using
GC.SuppressFinalize(this);.
If the developer does not call the
Dispose()method, the unmanaged resources are freed up in the destructor by the garbage collector. The figure below illustrates the solution:
Note: The
Dispose()method is used to free up the unmanaged resources, and calling
Dispose()will not free up the instance. It just executes whatever statements are written in it.
Using the Code
The code along with thisarticle demonstrates the case of using/not usingDispose(), and also the initiating of the
GarbageCollectionprocess using
GC.Collect(). Please analyze the
Channelclass to see the
details involved.
相关文章推荐
- 浅谈C#的垃圾回收-关于GC、析构函数、Dispose、and Finalize
- Dispose and Finalizer in C#
- Dispose and Finalize in Dot Net OR Maemory Management using Dispose and Finalize
- 浅谈C#的垃圾回收----关于GC、析构函数、Dispose、and Finalize
- Uploading File using Ajax and receiving binary data in Asp.net (C#)[转]
- (译)Asynchronous programming and Threading in C# (.NET 4.5)
- C#垃圾回收Finalize 和Dispose的理解
- Professional ASP.NET 3.5: In C# and VB
- How to create simple and advanced pivot tables in C# and ASP.NET
- 浅谈C#内存回收与Dispose﹐Close﹐Finalize方法 [转]
- C#垃圾回收Finalize 和Dispose的理解
- [C#]Finalize,Dispose,SuppressFinalize2
- SQL Server Database Backup and Restore in C#
- 7 Easy Steps to Learn C#: Silverlight C# Compiler and Loading DLLs from a server at runtime in Silverlight
- C# 中的Finalize 和Dispose(bool disposing)和 Dispose()
- java.lang.Object in Java and System.Object class in C#
- Covariance and Contravariance in C#的搜索条件
- managed and unmanaged code in c#
- Events and event handling in C#
- Pro .NET 2.0 Code and Design Standards in C# by Mark Horner