CA1816:正确调用 GC.SuppressFinalize

类型名

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

类别

Microsoft.用法

是否重大更改

原因

规则说明

使用 IDisposable.Dispose 方法,用户可以在可将对象作为垃圾回收之前随时释放资源。如果调用了 IDisposable.Dispose 方法,此方法会释放对象的资源。这使得无需终止。IDisposable.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 的方法。

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;
                }
            }
        }
    }
}

相关规则

CA2215:Dispose 方法应调用基类的 Dispose

CA2216:可释放类型应声明终结器

请参见

其他资源

Implementing Finalize and Dispose