Los tipos que poseen recursos nativos deben estar disponibles

Actualización: noviembre 2007

Nombre de tipo

TypesThatOwnNativeResourcesShouldBeDisposable

Identificador de comprobación

CA1049

Categoría

Microsoft.Design

Cambio problemático

No problemático

Motivo

Un tipo hace referencia a un campo System.IntPtr, un campo System.UIntPtr o un campo System.Runtime.InteropServices.HandleRef, pero no implementa System.IDisposable.

Descripción de la regla

Esta regla supone que IntPtr, UIntPtr y el almacén de campos HandleRef apunta a los recursos no administrados. Los tipos que se asignan a recursos no administrados deberían implementar IDisposable para permitir que los llamadores liberen estos recursos a petición y reduzcan el período de duración de los objetos que contienen los recursos.

El modelo de diseño recomendado para limpiar los recursos no administrados es proporcionar un modo implícito y otro explícito para liberar esos recursos utilizando el método Object.Finalize y el método IDisposable.Dispose respectivamente. El recolector de elementos no utilizados llama al método Finalize de un objeto en algún momento indeterminado después de que el objeto se establezca como no alcanzable. Después de llamar a Finalize, es necesario que la recolección de elementos no utilizados libere el objeto. El método Dispose permite que el llamador libere explícitamente recursos a petición, antes de que los recursos sean liberados si acaban en el recolector de elementos no utilizados. Después de limpiar los recursos no administrados, Dispose debe llamar al método GC.SuppressFinalize para permitir que el recolector de elementos no utilizados sepa que ya no es necesario llamar a Finalize; esto evita que el recolector de elementos no utilizados sea necesario y reduce el período de duración del objeto.

Cómo corregir infracciones

Para corregir una infracción de esta regla, implemente IDisposable.

Cuándo suprimir advertencias

Es seguro suprimir una advertencia de esta regla si el tipo no hace referencia a un recurso no administrado. De lo contrario, no suprima ninguna advertencia de esta regla como error, para implementar IDisposable puede hacer que los recursos no administrados se conviertan en no disponibles o infrautilizados.

Ejemplo

El ejemplo siguiente muestra un tipo que implementa IDisposable para limpiar un recurso no administrado.

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);
        }
    }
}

Reglas relacionadas

Llamar a GC.KeepAlive cuando se utilicen recursos nativos

Llamar a GC.SuppressFinalize correctamente

Los tipos disponibles deben declarar el finalizador

Los tipos que poseen campos desechables deben ser desechables

Vea también

Referencia

Implementar Finalize y Dispose para limpiar recursos no administrados

Otros recursos

Limpiar recursos no administrados