Типы, которым принадлежат собственные ресурсы, должны быть высвобождаемыми
Обновлен: Ноябрь 2007
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);
}
}
}
Связанные правила
Вызывайте GC.KeepAlive при использовании машинных ресурсов
Вызов GC.SuppressFinalize должен осуществляться правильно
Высвобождаемые типы должны объявлять метод завершения
Типы, которым принадлежат освобождаемые поля, должны быть освобождаемыми
См. также
Ссылки
Реализация методов Finalize и Dispose для очистки неуправляемых ресурсов