CA1816: вызов GC.SuppressFinalize должен осуществляться правильно
TypeName |
CallGCSuppressFinalizeCorrectly |
CheckId |
CA1816 |
Категория |
Microsoft. Использование |
Критическое изменение |
Не критическое |
Причина
Метод, являющийся реализацией IDisposable.Dispose, не вызывает GC.SuppressFinalize.
Метод, не являющийся реализацией IDisposable.Dispose, вызывает GC.SuppressFinalize.
Метод вызывает GC.SuppressFinalize и передает значение, отличное от данного ("Me" в Visual Basic).
Описание правила
Метод IDisposable.Dispose позволяет пользователям освобождать ресурсы в любое время, прежде чем объект становится доступным для сборки мусора. Если вызвать метод IDisposable.Dispose, ресурсы объекта будут очищены. Это делает финализацию ненужной. IDisposable.Dispose должен вызвать GC.SuppressFinalize, чтобы сборщик мусора не вызывал метод завершения объекта.
Чтобы исключить необходимость повторной реализации [System.IDisposable] производными типами с методами завершения, а также для его вызова, незапечатанные типы без методов завершения должны по-прежнему вызывать GC.SuppressFinalize.
Устранение нарушений
Чтобы устранить нарушение этого правила, выполните следующие действия
Если метод является реализацией Dispose, добавьте вызов GC.SuppressFinalize.
Если метод не является реализацией Dispose, удалите вызов GC.SuppressFinalize или переместите его в реализацию типа Dispose.
Измените все вызовы GC.SuppressFinalize для передачи этого (Me в Visual Basic).
Отключение предупреждений
Отключать вывод предупреждения по этому правилу следует только в том случае, если рассматривается возможность использования 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 должны вызывать такие же методы базового класса
CA2216: высвобождаемые типы должны объявлять метод завершения
См. также
Ссылки
Реализация методов Finalize и Dispose для очистки неуправляемых ресурсов