Поделиться через


CA1049: типы, которым принадлежат собственные ресурсы, должны быть высвобождаемыми

TypeName

TypesThatOwnNativeResourcesShouldBeDisposable

CheckId

CA1049

Категория

Microsoft.Design

Критическое изменение

Не критическое

Причина

Тип ссылается на поле System.IntPtr, поле System.UIntPtr или поле System.Runtime.InteropServices.HandleRef, но не реализует System.IDisposable.

Описание правила

Данное правило предполагает, что в полях IntPtr, UIntPtr и HandleRef хранятся указатели на неуправляемые ресурсы. Типы, выделяющие неуправляемые ресурсы, должны реализовывать IDisposable, чтобы вызывающие методы могли высвобождать эти ресурсы по требованию и сокращать время существования объектов, в которых хранятся ресурсы.

Рекомендуемым шаблоном разработки, используемым для освобождения неуправляемых ресурсов, является предоставление неявных и явных средств с помощью методов Object.Finalize и IDisposable.Dispose соответственно. Сборщик мусора вызывает метод Finalize объекта через некоторое неопределенное время после того, как данный объект определен как больше недоступный. После вызова метода Finalize для освобождения объекта требуется дополнительная сборка мусора. Метод Dispose позволяет вызывающим методам явным образом высвобождать ресурсы по требованию, причем это действие выполняется раньше, чем они были освобождены с помощью сборщика мусора. После высвобождения неуправляемых ресурсов Dispose должен вызывать метод GC.SuppressFinalize, чтобы сообщить сборщику мусора об отсутствии необходимости вызова Finalize, при этом сокращается время существования объекта и дополнительной сборки мусора не требуется.

Устранение нарушений

Чтобы устранить нарушение данного правила, реализуйте IDisposable.

Отключение предупреждений

Если тип не ссылается на неуправляемый ресурс, для данного правила можно отключить вывод предупреждений. В противном случае не отключайте вывод предупреждений для данного правила, поскольку сбой реализации IDisposable может привести к отсутствию доступа к неуправляемым ресурсам или к их недоиспользованию.

Пример

В следующем примере показан тип, реализующий IDisposable для освобождения неуправляемого ресурса.

Imports System

Namespace DesignLibrary

    Public Class UnmanagedResources
        Implements IDisposable

       Dim unmanagedResource As IntPtr
       Dim disposed As Boolean = False

       Sub New 
           ' Allocate the unmanaged resource ...
       End Sub

       Overloads Sub Dispose() Implements IDisposable.Dispose
           Dispose(True)
           GC.SuppressFinalize(Me)
       End Sub

       Protected Overloads Overridable Sub Dispose(disposing As Boolean)
           If Not(disposed) Then

               If(disposing) Then
                   ' Release managed resources.
               End If

               ' Free the unmanaged resource ...

               unmanagedResource = IntPtr.Zero

               disposed = True

           End If
       End Sub

       Protected Overrides Sub Finalize()
           Dispose(False)
       End Sub

    End Class

End Namespace
using System;

namespace DesignLibrary
{
    public class UnmanagedResources : IDisposable
    {
        IntPtr unmanagedResource;
        bool disposed = false;

        public UnmanagedResources() 
        {
            // Allocate the unmanaged resource ...
        }

        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this); 
        }

        protected virtual void Dispose(bool disposing)
        {
            if(!disposed)
            {
                if(disposing)
                {
                    // Release managed resources.
                }

                // Free the unmanaged resource ...

                unmanagedResource = IntPtr.Zero;

                disposed = true;
            }
        }

        ~UnmanagedResources()
        {
            Dispose(false);
        }
    }
}

Связанные правила

CA2115: вызывайте GC.KeepAlive при использовании собственных ресурсов

CA1816: вызов GC.SuppressFinalize должен осуществляться правильно

CA2216: высвобождаемые типы должны объявлять метод завершения

CA1001: типы, которым принадлежат освобождаемые поля, должны быть освобождаемыми

См. также

Ссылки

Реализация методов Finalize и Dispose для очистки неуправляемых ресурсов

Другие ресурсы

Очистка неуправляемых ресурсов