Sdílet prostřednictvím


CA1816: Volejte správně GC.SuppressFinalize

TypeName

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

Kategorie

Microsoft.Použití

Narušující změna

Nenarušující

Příčina

Popis pravidla

Metoda IDisposable.Dispose umožňuje uživateli kdykoliv uvolnit zdroje, než je objekt k dispozici pro systém uvolňování paměti.Je-li zavolána metoda IDisposable.Dispose, uvolňuje zdroje objektu.Díky tomu není nezbytná finalizace.Metoda IDisposable.Dispose by měla volat metodu GC.SuppressFinalize, aby systém uvolňování paměti nevolal finalizační metodu objektu.

 

Chcete-li zabránit nutnosti odvozených typů s finalizačními metodami znovu implementovat rozhraní [System.IDisposable] a volat jej, měly by nezapečetěné typy bez finalizačních metod stále volat metodu GC.SuppressFinalize.

Jak vyřešit porušení

Chcete-li opravit porušení tohoto pravidla:

Je-li metoda implementací metody Dispose, přidejte volání metody GC.SuppressFinalize.

Pokud metoda není implementací metody Dispose, odeberte volání metody GC.SuppressFinalize nebo ji přesuňte do implementace metody Dispose daného typu.

Změňte všechna volání metody GC.SuppressFinalize tak, aby předávala parametr this (Me v jazyce Visual Basic).

Kdy potlačit upozornění

Potlačte upozornění tohoto pravidla pouze v případě, že záměrně používáte metodu GC.SuppressFinalize pro řízení životního cyklu jiných objektů.Upozornění tohoto pravidla nepotlačujte, pokud implementace metody Dispose nevolá metodu GC.SuppressFinalize.Není-li potlačena finalizace, dojde v takové situaci ke zbytečnému snížení výkonu.

Příklad

Následující příklad ukazuje metodu, která nesprávně volá metodu 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;
                }
            }
        }
    }
}

Následující příklad ukazuje metodu, která správně volá metodu 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;
                }
            }
        }
    }
}

Související pravidla

CA2215: Metody Dispose by měly volat uvolnění třídy Base

CA2216: Uvolnitelné typy by měly deklarovat finalizační metodu

Viz také

Další zdroje

Implementing Finalize and Dispose