-
使用析构函数释放资源
析构函数用于析构类的实例。
1)
不能在结构中定义析构函数。只能对类使用析构函数。
2)
一个类只能有一个析构函数。
3)
无法继承或重载析构函数。
4)
无法调用析构函数。它们是被自动调用的。
5)
析构函数既没有修饰符,也没有参数。
例如,下面是类
Car
的析构函数的声明:
[csharp] view plaincopy
class Car
{
///
///
析构函数
///
~Car()
{
//
cleanup statements...
}
}
该析构函数隐式地调用对象基类的
F
inalize
。这样,该析构函数被隐式地转换为如下代码:
[csharp] view plaincopy
protected override void Finalize()
{
try
{
//
Cleanup statements...
}
finally
{
ze();
}
}
这意味着对继承链中的所有实例递归地调用
Finalize
方法。
说明:
不要使用空的析构函数。
如果类包含析构
函数,
则
Finalize
队列中则会创建一个项。
当调用析构
函数时,将调用垃圾回收器(
GC
)来处理该队列。如果析构函
数为空,只会导
致不必要的性能损失。
程序员无法控制何时调用析构函数,
因为这是由垃圾回收器决定的。
< br>垃圾回收器检查是否存
在应用程序不再使用的对象。
如果
垃圾回收器认为某个对象符合析构,
则调用析构函数
(如
果有的话)
,回收该对象的内存。程序退出时也会调用析构函数。
p>
可以通过调用
Collect
强制进行垃圾回收,但大多数情况下应避免这
样做,
因为会导致性能
问题。
通常,
.NET
Framework
垃圾回收器会隐式地管理对象的内存分配和释放。但当应用程序封
装窗口、
文件和网络连接这类非托管资源时,
应使用析构函数
释放这些资源。
当对象符合析
构时,垃圾回收器将运行对象的<
/p>
Finalize
方法。
虽然垃圾回收器可以跟踪封装
非托管资源的对象的生存期,
但它不了解具体如何清理这些资
源
。
常见的非托管源有:
ApplicationContext
、
Brush
、
Component
、
ComponentDesigner
、
Container
、
Context
、
Cursor
、
FileStream
、
Fon
t
、
Icon
、
Image
、
Matrix
、
Object
、
OdbcDataReade
r
、
OleDBDataReader
、
Pen
、
Regex
、
Socket
、
Strea
mWriter
、
Timer
、
Tooltip
等。
ze
方法
允许
Object
在
“垃圾回收”
回收
Object
之前尝试释放资源并执行其他清理操作。
Finalize <
/p>
是
受保护的,因此只能通过此类或派生类访问它。
对象变为不可访问后,将自动调用此方法,除非已通过
ssFinalize
调用使对象
免
除了终结。在应用程序域的关闭过程中,对没有免除终结的对象将自动调用
Finalize
,即使
那
些
对
象
仍
是
可
访
问
p>
的
。
对
于
给
定
的
实
例
仅
自
动
< br>调
用
Finalize
p>
一
次
,
除
非
使
用
sterForFinalize
重
新注册该对象,并且后面没有调用
ssFinalize
。
p>
派生类型中的每个
Finalize
实现都必须调用其基类型的
Finalize
实现。
这是唯一一
种允许应
用程序代码调用
Finalize
的情况。
注意:
C#
编译器不允许你直接实现
Finalize
方法,因此
C#
析构函数自动调用其基类的析
构函数。
Finalize
操作具有下列限制:
1)
垃圾回收过程中执行终结器的准确
时间是不确定的。不保证资源在任何特定的时间都
能释放,除非调用
Close
方法或
Dispose
方法。
2)
即
使一个对象引用另一个对象,
也不能保证两个对象的终结器以任何特定的顺序运行。
p>
即,如果对象
A
具有对对象
B
的引用,并且两者都有终结器,则当对象
A
的终结器启动
时,对象
B
可能已经终结了。
3)
运行终结器的线程是未指定的。
在下面的异常情况下,
Finalize
方法可能不会运行完成或可能根本不运行:
1)
另
一个终结器无限期地阻止
(进入无限循环,
试图获取永远无法获
取的锁,
诸如此类)
。
由于运行时试图
运行终结器来完成,
所以如果一个终结器无限期地阻止,
则可能
不会调用其
他终结器。
2)
进程终止,但不给运行时提供清理
的机会。在这种情况下,运行时的第一个进程终止
通知是
DLL_PROCESS_DETACH
通知。
在关闭过程中,只有当可终结
对象的数目继续减少时,运行时才继续
Finalize
对象。
如果
Finalize
或
Finalize
的重写引发异常,
并且运行库并非寄宿在重写默认策略的应用程序
中,
则运行库将
终止进程,并且不执行任何活动的
try-finally
块或终结器。
如果终结器无法
释放或销
毁资源,此行为可以确保进程完整性。
说明:
默认情况下,
ze
不执行任何操作。
只有在必要时才必须由派生类重写它,
< br>因为如果必须运行
Finalize
操作,垃圾回收过程中的回收往往需要长得多的时间。如果
Object
保存了对任何资源的引用,
则
Finalize
必须由派生类重写,
以便在垃圾回收过程中,
在放弃
Object
之前释放这些资源。
当
类型使用文件句柄或数据库连接这类在回收使用托管
对象时必须释放的非托管资源时,<
/p>
该类型必须实现
Finalize
。
Finalize
可以采取任何操作,
包
括在垃圾回收过
程中清理了对象后使对象复活(即,使对象再次可访问)
。但是,对象只能
复活一次;在垃圾回收过程中,不能对复活对象调用
Finalize
。
析构函数是执行清理操作的
C# <
/p>
机制。
析构函数提供了适当的保护措施,
如自动调用基类型
的析构函数。在
C#
代码中,不能调用或重写
ze
。
示例
下面例子验证,当一个重构
Finalize
方法的对象被销毁时,会调用
Finalize
方法。注意,在
-
-
-
-
-
-
-
-
-
上一篇:八年级文言文词类活用
下一篇:十大词性