using 资源清理
(三)资源清理
由来:
要理解清楚使用using语句强制清理资源,就首先从了解Dispose模式说起,而要了解Dispose模式,则应首先了解.NET的垃圾回收机制。 .NET提供了Dispose模式来实现显式释放和关闭对象的能力。
Dispose模式
Dispose模式是.NET提供的一种显式清理对象资源的约定方式,用于在.NET 中释放对象封装的非托管资源。因为非托管资源不受GC控制,对象必须调用自己的Dispose()方法来释放,这就是所谓的Dispose模式。从概念角度来看,Dispose模式就是一种强制资源清理所要遵守的约定;从实现角度来看,Dispose模式就是让要一个类型实现IDisposable接口,从而使得该类型提供一个公有的Dispose方法。
using语句提供了强制清理对象资源的便捷操作方式,允许指定何时释放对象的资源源。
所有拥有非托管资源的类型都会实现Idisposable接口,如果我们忘记Dispose()方法,其中的非内存资源会在随后终结器执行时释放,这样对象在内存中存放的时间就比较长,应用程序对资源的清理比较慢。
C#中的using语句可以Dispose()方法被调用,我们可以在using语句中分配一个对象,C#编译器会为每一个对象自动产生一个try/finally块。
下面的两端代码将生成一样的IL代码。
string connStr = string.Empty;
SqlConnection conn = null;
//using 语句示例
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
}
//try/finally块
try
{
conn = new SqlConnection(connStr);
conn.Open();
}
finally
{
conn.Dispose();
}
误区:
(1)对没有实现Idisposable()接口的对象使用using语句。
例子:
//object对象没有实现Idisposeable接口
Using (object obj = Factory.CreateResource())
{
Console.WriteLine(obj.ToString());
}
//修正版本
Object obj=Factory.CreateResource();
Using (obj as Idsposeable)
{
Console.WriteLine(obj.ToString());
}
如果没有实现Idisopose接口,在上面的情况下,using语句退化为using(null),这种做法非常的安全,只是不会做任何的事情。
(2) 潜在的资源泄漏
SqlConnection conn=new SqlConnection(connStr);
SqlCommand cmd=new SqlCommand(cmdStr,conn);
Using(conn as IDisposeable)
Using (cmd as Idisposeable)
{
conn.Open();
cmd.ExecuteNonQuery();
}
确保任何实现了Idisposeable()接口的对象都在using和Try块中分配,否则有可能出现内存泄漏。
一个方法中有多个需要释放的资源的对象时,可以创建多个using块,或者自己写一个try/finally块,两种方法是等效的,产生的IL代码是完全一样的。
有些对象既实现了Dispose()又实现了Close()。
Dispose()除了释放资源外,还会通知垃圾回收器这个对象不再需要终结操作。Dispose()通过GC.SuppressFinaize()方法来实现这一点,Close()一般不会这么做。因此调用过Close()的对象仍然留在终结队列中,Dispose()不会将对象从内存中删除,它只是让对象释放非托管资源。
本篇文章来源于IceCeo网 原文链接:http://www.iceceo.cn/article/info-267.html