Share via


CA1816: GC.SuppressFinalize korrekt aufrufen

TypeName

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

Kategorie

Microsoft Verwendung

Unterbrechende Änderung

Nicht unterbrechend

Ursache

Regelbeschreibung

Mit der IDisposable.Dispose-Methode können die Benutzer Ressourcen jederzeit freigeben, bevor das Objekt für die Garbage Collection verfügbar wird. Wenn die IDisposable.Dispose-Methode aufgerufen wird, werden Ressourcen des Objekts freigegeben. Dies macht einen Abschluss unnötig. IDisposable.Dispose sollte GC.SuppressFinalize aufrufen, damit der Garbage Collector nicht den Finalizer des Objekts aufruft.

 

Um zu verhindern, dass abgeleitete Typen mit Finalizern [System.IDisposable] erneut implementieren und aufrufen müssen, sollten unversiegelte Typen ohne Finalizer dennoch GC.SuppressFinalize aufrufen.

Behandeln von Verstößen

So korrigieren Sie einen Verstoß dieser Regel:

Wenn die Methode eine Implementierung von Dispose ist, fügen Sie einen Aufruf von GC.SuppressFinalize hinzu.

Wenn die Methode keine Implementierung von Dispose ist, entfernen Sie den Aufruf von GC.SuppressFinalize, oder verschieben Sie ihn in die Implementierung von Dispose des Typs.

Ändern Sie alle Aufrufe in GC.SuppressFinalize, sodass sie dies (Me in Visual Basic) übergeben.

Wann sollten Warnungen unterdrückt werden?

Unterdrücken Sie eine Warnung dieser Regel nur, wenn Sie GC.SuppressFinalize zur Steuerung der Lebensdauer anderer Objekte verwenden möchten. Unterdrücken Sie keine Warnung dieser Regel, wenn eine Implementierung von Dispose nicht GC.SuppressFinalize aufruft. Wird der Abschluss nicht unterdrückt, beeinträchtigt dies die Leistung, sodass sich keine Vorteile ergeben.

Beispiel

Im folgenden Beispiel wird eine Methode veranschaulicht, die nicht korrekt GC.SuppressFinalize aufruft.

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

Im folgenden Beispiel wird eine Methode veranschaulicht, die ordnungsgemäß GC.SuppressFinalize aufruft.

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

Verwandte Regeln

CA2215: Dispose-Methoden müssen die Dispose-Funktion der Basisklasse aufrufen

CA2216: Verwerfbare Typen sollten einen Finalizer deklarieren

Siehe auch

Referenz

Implementieren der Methoden "Finalize" und "Dispose" zum Bereinigen von nicht verwalteten Ressourcen