在.NET中很多托管资源都实现了IDisposable接口,这个接口只有一个待实现的方法Dispose(),在上面提到的类中大都有这个方法,此外还有些类除了调用Dispose()方法可以释放资源之外,还可以调用Close()方法释放资源,比如各类数据库连接(Connection)、各种流(Stream),在调用Close()方法时会自动调用Dispose()方法的。
在.net 编程环境中,系统的资源分为托管资源和非托管资源。
对于托管的资源的回收工作,是不需要人工干预回收的,而且你也无法干预他们的回收,所能够做的只是了解.net CLR如何做这些操作。也就是说对于您的应用程序创建的大多数对象,可以依靠 .NET Framework 的垃圾回收器隐式地执行所有必要的内存管理任务。
对于非托管资源,您在应用程序中使用完这些非托管资源之后,必须显示的释放他们,例如System.IO.StreamReader的一个文件对象,必须显示的调用对象的Close()方法关闭它,否则会占用系统的内存和资源,而且可能会出现意想不到的错误。
我想说到这里,一定要清楚什么是托管资源,什么是非托管资源了?
最常见的一类非托管资源就是包装操作系统资源的对象,例如文件,窗口或网络连接,对于这类资源虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。还好.net Framework提供了Finalize()方法,它允许在垃圾回收器回收该类资源时,适当的清理非托管资源。如果在MSDN Library 中搜索Finalize将会发现很多类似的主题,这里列举几种常见的非托管资源:ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Timer,Tooltip 等等资源。可能在使用的时候很多都没有注意到!
关于托管资源,就不用说了撒,像简单的int,string,float,DateTime等等,.net中超过80%的资源都是托管资源。
非托管资源如何释放,.NET Framework 提供 Object.Finalize 方法,它允许对象在垃圾回收器回收该对象使用的内存时适当清理其非托管资源。默认情况下,Finalize 方法不执行任何操作。默认情况下,Finalize 方法不执行任何操作。如果您要让垃圾回收器在回收对象的内存之前对对象执行清理操作,您必须在类中重写 Finalize 方法。然而大家都可以发现在实际的编程中根本无法override方法Finalize(),在C#中,可以通过析构函数自动生成 Finalize 方法和对基类的 Finalize 方法的调用。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
~MyClass()
{
// Perform some cleanup operations here.
}
该代码隐式翻译为下面的代码。
protected
override
void
Finalize()
{
try
{
// Perform some cleanup operations here.
}
finally
{
base
.Finalize();
}
}
|
1
2
3
4
5
6
7
|
class
Myclass : IDisposable
{
public
void
Dispose()
{
// implementation
}
}
|
1
2
3
4
5
|
ResourceGobbler theInstance =
new
ResourceGobbler();
// 这里是theInstance 对象的使用过程
theInstance.Dispose();
|
1
2
3
4
5
6
7
8
9
10
|
ResourceGobbler theInstance =
null
;
try
{
theInstance =
new
ResourceGobbler();
// 这里是theInstance 对象的使用过程
}
finally
{
if
(theInstance !=
null
) theInstance.Dispose();
}
|
1
2
3
4
|
using
(ResourceGobbler theInstance =
new
ResourceGobbler())
{
// 这里是theInstance 对象的使用过程
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public
class
ResourceHolder : IDisposable
{
private
bool
isDispose =
false
;
// 显示调用的Dispose方法
public
void
Dispose()
{
Dispose(
true
);
GC.SuppressFinalize(
this
);
}
// 实际的清除方法
protected
virtual
void
Dispose(
bool
disposing)
{
if
(!isDisposed)
{
if
(disposing)
{
// 这里执行清除托管对象的操作.
}
// 这里执行清除非托管对象的操作
}
isDisposed=
true
;
}
// 析构函数
~ResourceHolder()
{
Dispose (
false
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public
class
DisposeClass:IDisposable
{
public
void
Close()
{
Debug.WriteLine(
"Close called!"
);
}
~DisposeClass()
{
Debug.WriteLine(
"Destructor called!"
);
}
#region IDisposable Members
public
void
Dispose()
{
// TODO: Add DisposeClass.Dispose implementation
Debug.WriteLine(
"Dispose called!"
);
}
#endregion
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
private
void
Create()
{
DisposeClass myClass =
new
DisposeClass();
}
private
void
CallGC()
{
GC.Collect();
}
// Show destructor
Create();
Debug.WriteLine(
"After created!"
);
CallGC();
|
1
2
3
4
5
6
7
|
using
( DisposeClass myClass =
new
DisposeClass() )
{
//other operation here
}
|
http://bbs.csdn.net/topics/320129095