다음을 통해 공유


CA1816: GC.SuppressFinalize를 올바르게 호출하십시오.

TypeName

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에 대한 모든 호출을 이곳으로 전달하도록 변경합니다(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: 삭제 가능한 형식은 종료자를 선언해야 합니다.

참고 항목

참조

Finalize 및 Dispose를 구현하여 관리되지 않는 리소스 정리