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