示例

下面的示例验证当重Finalize写Finalize的对象被销毁时调用的方法。The following example verifies that the Finalize method is called when an object that overrides Finalize is destroyed.请注意，在生产应用程序中， Finalize将重写方法以释放由该对象占用的非托管资源。Note that, in a production application, the Finalize method would be overridden to release unmanaged resources held by the object.另请注意， C#该示例提供析构函数，而不Finalize是重写方法。Also note that the C# example provides a destructor instead of overriding the Finalize method.

using System;
using System.Diagnostics;
public class ExampleClass
{
Stopwatch sw;
public ExampleClass()
{
sw = Stopwatch.StartNew();
Console.WriteLine("Instantiated object");
}
public void ShowDuration()
{
Console.WriteLine("This instance of {0} has been in existence for {1}",
this, sw.Elapsed);
}
~ExampleClass()
{
Console.WriteLine("Finalizing object");
sw.Stop();
Console.WriteLine("This instance of {0} has been in existence for {1}",
this, sw.Elapsed);
}
}
public class Demo
{
public static void Main()
{
ExampleClass ex = new ExampleClass();
ex.ShowDuration();
}
}
// The example displays output like the following:
// Instantiated object
// This instance of ExampleClass has been in existence for 00:00:00.0011060
// Finalizing object
// This instance of ExampleClass has been in existence for 00:00:00.0036294

Imports System.Diagnostics
Public Class ExampleClass
Dim sw As StopWatch
Public Sub New()
sw = Stopwatch.StartNew()
Console.WriteLine("Instantiated object")
End Sub
Public Sub ShowDuration()
Console.WriteLine("This instance of {0} has been in existence for {1}",
Me, sw.Elapsed)
End Sub
Protected Overrides Sub Finalize()
Console.WriteLine("Finalizing object")
sw.Stop()
Console.WriteLine("This instance of {0} has been in existence for {1}",
Me, sw.Elapsed)
End Sub
End Class
Module Demo
Public Sub Main()
Dim ex As New ExampleClass()
ex.ShowDuration()
End Sub
End Module
' The example displays output like the following:
' Instantiated object
' This instance of ExampleClass has been in existence for 00:00:00.0011060
' Finalizing object
' This instance of ExampleClass has been in existence for 00:00:00.0036294

注解

Finalize方法用于在销毁对象之前对当前对象占用的非托管资源执行清理操作。The Finalize method is used to perform cleanup operations on unmanaged resources held by the current object before the object is destroyed.方法是受保护的，因此只能通过此类或派生类访问。The method is protected and therefore is accessible only through this class or through a derived class.

如果类型确实重写Finalize方法，则垃圾回收器会将类型的每个实例的条目添加到称为终止队列的内部结构。If a type does override the Finalize method, the garbage collector adds an entry for each instance of the type to an internal structure called the finalization queue.终止队列包含托管堆中的所有对象的条目，在垃圾回收器可以回收内存之前，必须先运行终止代码。The finalization queue contains entries for all the objects in the managed heap whose finalization code must run before the garbage collector can reclaim their memory.然后，垃圾回收器会Finalize在以下条件下自动调用方法：The garbage collector then calls the Finalize method automatically under the following conditions:

在垃圾回收器发现对象不可访问后，除非已通过调用GC.SuppressFinalize方法免除了该对象的终止。After the garbage collector has discovered that an object is inaccessible, unless the object has been exempted from finalization by a call to the GC.SuppressFinalize method.

仅在 .NET Framework的情况下，在应用程序域的关闭过程中，除非该对象免于终止。On .NET Framework only, during shutdown of an application domain, unless the object is exempt from finalization.在关闭期间，即使仍可访问的对象也会完成。During shutdown, even objects that are still accessible are finalized.

不确定终结器执行时的准确时间。The exact time when the finalizer executes is undefined.若要确保类的实例的资源的确定性版本，请实现Close方法或IDisposable.Dispose提供实现。To ensure deterministic release of resources for instances of your class, implement a Close method or provide a IDisposable.Dispose implementation.

不能保证两个对象的终结器以任何特定顺序运行，即使一个对象引用另一个对象也是如此。The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other.也就是说，如果对象 A 具有对对象 B 的引用，并且都具有终结器， 在对象 A 的终结器启动时，对象 B 可能已被终结。That is, if Object A has a reference to Object B and both have finalizers, Object B might have already been finalized when the finalizer of Object A starts.

不指定终结器在其上运行的线程。The thread on which the finalizer runs is unspecified.

在Finalize以下异常情况下，该方法可能无法运行到完成或根本不会运行：The Finalize method might not run to completion or might not run at all under the following exceptional circumstances:

如果另一个终结器无限期阻止（进入无限循环，则会尝试获取它永远无法获取的锁定，等等）。If another finalizer blocks indefinitely (goes into an infinite loop, tries to obtain a lock it can never obtain, and so on).因为运行时尝试运行终结器来完成，所以如果终结器无限期阻塞，则可能不会调用其他终结器。Because the runtime tries to run finalizers to completion, other finalizers might not be called if a finalizer blocks indefinitely.

如果进程终止，无需给运行时提供清理的机会。If the process terminates without giving the runtime a chance to clean up.在这种情况下，运行时的进程终止通知是 DLL_PROCESS_DETACH 通知。In this case, the runtime's first notification of process termination is a DLL_PROCESS_DETACH notification.

仅在关闭过程中，运行时继续完成对象，但可继续减少可终结对象的数量。The runtime continues to finalize objects during shutdown only while the number of finalizable objects continues to decrease.

如果Finalize或的Finalize替代引发了异常，并且运行时不是由覆盖默认策略的应用程序承载，则运行时将终止进程，而不会try终止活动/ finally块或执行终结器。If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process and no active try/finally blocks or finalizers are executed.如果终结器无法释放或销毁资源，则此行为可确保进程完整性。This behavior ensures process integrity if the finalizer cannot free or destroy resources.

重写 Finalize 方法Overriding the Finalize method

应为使用Finalize非托管资源的类（例如，在垃圾回收过程中丢弃使用非托管资源的文件句柄或数据库连接）进行重写。You should override Finalize for a class that uses unmanaged resources, such as file handles or database connections that must be released when the managed object that uses them is discarded during garbage collection.不应实现Finalize托管对象的方法，因为垃圾回收器会自动释放托管资源。You shouldn't implement a Finalize method for managed objects because the garbage collector releases managed resources automatically.

默认Object.Finalize情况下，此方法不执行任何操作， Finalize但你应仅在必要时重写，并且仅释放非托管资源。The Object.Finalize method does nothing by default, but you should override Finalize only if necessary, and only to release unmanaged resources.如果某个终止操作运行，则回收内存要花费更长时间，因为它需要至少两个垃圾回收。Reclaiming memory tends to take much longer if a finalization operation runs, because it requires at least two garbage collections.此外，还应为仅引用Finalize类型重写方法。In addition, you should override the Finalize method for reference types only.公共语言运行时仅终结引用类型。The common language runtime only finalizes reference types.它忽略值类型上的终结器。It ignores finalizers on value types.

该Object.Finalize方法的范围为protected。The scope of the Object.Finalize method is protected.重写类中的方法时，应保持此有限范围。You should maintain this limited scope when you override the method in your class.通过使Finalize方法受到保护，可以防止应用程序的用户直接调用对象的Finalize方法。By keeping a Finalize method protected, you prevent users of your application from calling an object's Finalize method directly.

派生类型中Finalize的每个实现都必须调用其基类型的Finalize实现。Every implementation of Finalize in a derived type must call its base type's implementation of Finalize.这是允许应用程序代码调用Finalize的唯一情况。This is the only case in which application code is allowed to call Finalize.对象的Finalize方法不应在其基类以外的任何对象上调用方法。An object's Finalize method shouldn't call a method on any objects other than that of its base class.这是因为调用的其他对象可以与调用对象同时收集，如公共语言运行时关闭的情况。This is because the other objects being called could be collected at the same time as the calling object, such as in the case of a common language runtime shutdown.

备注

C#编译器不允许重写Finalize方法。The C# compiler does not allow you to override the Finalize method.而是通过实现类的析构函数来提供终结器。Instead, you provide a finalizer by implementing a destructor for your class.C#析构函数自动调用其基类的析构函数。A C# destructor automatically calls the destructor of its base class.

由于垃圾回收是不确定的，因此，在垃圾回收器执行终止时，您不会精确地知道。Because garbage collection is non-deterministic, you do not know precisely when the garbage collector performs finalization.若要立即释放资源，还可以选择实现dispose 模式和IDisposable接口。To release resources immediately, you can also choose to implement the dispose pattern and the IDisposable interface.实现可由类的使用者调用以释放非托管资源，并且可以Dispose在未调用方法Finalize的情况下使用方法来释放非托管资源。 IDisposable.DisposeThe IDisposable.Dispose implementation can be called by consumers of your class to free unmanaged resources, and you can use the Finalize method to free unmanaged resources in the event that the Dispose method is not called.

Finalize几乎可以执行任何操作，包括 resurrecting 一个对象（即，在垃圾回收过程中清除对象后使对象再次可访问）。Finalize can take almost any action, including resurrecting an object (that is, making the object accessible again) after it has been cleaned up during garbage collection.但是，对象只能复活一次;Finalize在垃圾回收期间，不能对复活对象调用。However, the object can only be resurrected once; Finalize cannot be called on resurrected objects during garbage collection.

下面的示例将dispose 模式与安全句柄一起使用，而Finalize不是重写方法。The following example uses the dispose pattern with safe handles instead of overriding the Finalize method.它定义一个FileAssociation类，该类包装有关处理具有特定文件扩展名的文件的应用程序的注册表信息。It defines a FileAssociation class that wraps registry information about the application that handles files with a particular file extension.Windows RegOpenKeyEx函数调用SafeRegistryHandle将两out个作为参数返回的注册表句柄传递到构造函数。The two registry handles returned as out parameters by Windows RegOpenKeyEx function calls are passed to the SafeRegistryHandle constructor.然后，该类型Dispose的受保护方法SafeRegistryHandle.Dispose会调用方法来释放这两个句柄。The type's protected Dispose method then calls the SafeRegistryHandle.Dispose method to free these two handles.