Ordnungsgemäßes Aufrufen von GC.SuppressFinalize

Aktualisiert: November 2007

     TypeName

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

Kategorie

Microsoft Verwendung

Unterbrechende Änderung

Nicht unterbrechend

Ursache

Eine Methode, die eine Implementierung von Dispose ist, ruft GC.SuppressFinalize nicht auf.

- oder -

Eine Methode, die keine Implementierung von Dispose ist, ruft GC.SuppressFinalize auf.

- oder -

Eine Methode ruft GC.SuppressFinalize auf und übergibt etwas anderes als this (Me in Visual Basic).

Regelbeschreibung

Mit der Dispose-Methode können die Benutzer Ressourcen jederzeit freigeben, bevor das Objekt für die Garbage Collection verfügbar wird. Wenn die Dispose-Methode aufgerufen wird, werden Ressourcen des Objekts freigegeben. Dadurch wird ein Abschluss des Objekts unnötig. 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.

Behandlung 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 von GC.SuppressFinalize, sodass sie this (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 dargestellt, die GC.SuppressFinalize nicht ordnungsgemäß aufruft, da true (True in Visual Basic) übergeben wird.

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

Verwerfbare Typen sollten einen Finalizer deklarieren

Siehe auch

Referenz

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