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