Udostępnij za pośrednictwem


CA1816: Wywołaj poprawnie GC.SuppressFinalize

TypeName

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

Kategoria

Microsoft.Użycie

Zmiana kluczowa

Niekluczowa

Przyczyna

Opis reguły

Metoda IDisposable.Dispose pozwala użytkownikom zwolnić zasoby w dowolnym momencie, zanim obiekt stanie się dostępny dla mechanizmu wyrzucania elementów bezużytecznych.Jeśli metoda IDisposable.Dispose jest wywoływana, zwalnia zasoby obiektu.Z tego powodu finalizacja nie jest konieczna.Metoda IDisposable.Dispose powinna wywołać metodę GC.SuppressFinalize, aby mechanizm wyrzucania elementów bezużytecznych nie wywoływał finalizatora obiektu.

 

Aby zapobiec konieczności ponownej implementacji [System.IDisposable] typów dziedziczonych i aby ją wywołać, typy niezapieczętowane bez finalizatorów powinny nadal wywoływać GC.SuppressFinalize.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły:

Jeśli metoda jest implementacją Dispose, dodaj wywołanie GC.SuppressFinalize.

Jeśli metoda nie jest implementacją Dispose, usuń wywołanie GC.SuppressFinalize lub przenieś je do implementacji typu Dispose.

Zmień wszystkie wywołania GC.SuppressFinalize, aby przekazywały this (Me w języku Visual Basic).

Kiedy pominąć ostrzeżenia

Pomiń ostrzeżenie i odstąp od tej reguły, tylko jeśli rozważasz użycie GC.SuppressFinalize do kontrolowania okresu istnienia innych obiektów.Nie pomijaj ostrzeżenia dotyczącego tej reguły, jeśli implementacja Dispose nie wywołuje GC.SuppressFinalize.W takiej sytuacji, jeśli finalizacja nie zostanie pominięta, obniżona zostanie wydajność i nie przyniesie żadnych korzyści.

Przykład

Poniższy przykład pokazuje metodę, która niepoprawnie wywołuje 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;
                }
            }
        }
    }
}

Poniższy przykład pokazuje metodę, która poprawnie wywołuje 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;
                }
            }
        }
    }
}

Powiązane reguły

CA2215: Metody Dispose powinny wywoływać operację usuwania klasy podstawowej

CA2216: Typy usuwalne powinny deklarować finalizator

Zobacz też

Inne zasoby

Implementing Finalize and Dispose