Compartir a través de


CA1049: Los tipos que poseen recursos nativos deben ser descartables

Nombre de tipo

TypesThatOwnNativeResourcesShouldBeDisposable

Identificador de comprobación

CA1049

Categoría

Microsoft.Design

Cambio problemático

Poco problemático

Causa

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 mediante 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 que limpia los recursos no administrados, Dispose debe llamar al método GC.SuppressFinalize para permitir que la recolección de elementos no utilizados sepa que ya no es necesario llamar a Finalize; esto evita que sea necesaria la recolección de elementos no utilizados 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. En caso contrario, no suprima ninguna advertencia de esta regla, porque si no se implementa IDisposable puede hacer que los recursos no administrados queden 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

CA2115: Llamar a GC.KeepAlive cuando se utilicen recursos nativos

CA1816: Llamar a GC.SuppressFinalize correctamente

CA2216: Los tipos descartables deben declarar el finalizador

CA1001: Los tipos que poseen campos descartables deben ser descartables

Vea también

Referencia

Implementar Finalize y Dispose para limpiar recursos no administrados

Otros recursos

Limpiar recursos no administrados