Share via


正确调用 GC.SuppressFinalize

更新:2007 年 11 月

TypeName

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

类别

Microsoft.Usage

是否重大更改

原因

作为 Dispose 的实现的方法没有调用 GC.SuppressFinalize

- 或 -

不是 Dispose 的实现的方法调用了 GC.SuppressFinalize

- 或 -

方法调用了 GC.SuppressFinalize 并且传递的内容不是 this(在 Visual Basic 中为 Me)。

规则说明

使用 Dispose 方法,用户可以在可将对象作为垃圾回收之前随时释放资源。如果调用了 Dispose 方法,此方法会释放对象的资源。这样,就没有必要进行终止。Dispose 应调用 GC.SuppressFinalize 以使垃圾回收器不调用对象的终结器。

若要使带有终结器的派生类型无需重新实现 [System.IDisposable] 和调用它,不带终结器的非密封类型仍然应调用 GC.SuppressFinalize

如何修复冲突

若要修复与该规则的冲突,请执行以下操作:

如果相应方法是 Dispose 的实现,请添加对 GC.SuppressFinalize 的调用。

如果相应方法不是 Dispose 的实现,请移除对 GC.SuppressFinalize 的调用或将其移到相应类型的 Dispose 实现中。

将对 GC.SuppressFinalize 的所有调用更改为传递 this(在 Visual Basic 中为 Me)。

何时禁止显示警告

只有在您考虑使用 GC.SuppressFinalize 来控制其他对象的生存期时,才应禁止显示此规则发出的警告。如果 Dispose 的实现没有调用 GC.SuppressFinalize,请勿禁止显示此规则发出的警告。在这种情况下,如果取消终止失败,则会使性能下降且不会有任何好处。

示例

下面的示例演示一个方法,该方法向 GC.SuppressFinalize 传递了 true(在 Visual Basic 中为 true),从而对其进行了错误调用。

Imports System
Imports System.Data.SqlClient

Namespace Samples

    Public Class DatabaseConnector
        Implements IDisposable

        Private _Connection As New SqlConnection

        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(True)   ' Violates rules
        End Sub

        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If _Connection IsNot Nothing Then
                    _Connection.Dispose()
                    _Connection = Nothing
                End If
            End If
        End Sub

    End Class

End Namespace
using System;
using System.Data.SqlClient;
namespace Samples
{
    public class DatabaseConnector : IDisposable
    {
        private SqlConnection _Connection = new SqlConnection();

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(true);  // Violates rule
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_Connection != null)
                {
                    _Connection.Dispose();
                    _Connection = null;
                }
            }
        }
    }
}

下面的示例显示了一个正确调用 GC.SuppressFinalize 的方法。

Imports System
Imports System.Data.SqlClient

Namespace Samples

    Public Class DatabaseConnector
        Implements IDisposable

        Private _Connection As New SqlConnection

        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub

        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If _Connection IsNot Nothing Then
                    _Connection.Dispose()
                    _Connection = Nothing
                End If
            End If
        End Sub

    End Class

End Namespace
using System;
using System.Data.SqlClient;

namespace Samples
{
    public class DatabaseConnector : IDisposable
    {
        private SqlConnection _Connection = new SqlConnection();

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_Connection != null)
                {
                    _Connection.Dispose();
                    _Connection = null;
                }
            }
        }
    }
}

相关规则

可释放类型应声明终结器

请参见

参考

实现 Finalize 和 Dispose 以清理非托管资源