I tipi delle risorse native devono essere disposable
Aggiornamento: novembre 2007
TypeName |
TypesThatOwnNativeResourcesShouldBeDisposable |
CheckId |
CA1049 |
Category |
Microsoft.Design |
Breaking Change |
Non sostanziale |
Causa
Un tipo fa riferimento a un campo System.IntPtr, a un campo System.UIntPtr o a un campo System.Runtime.InteropServices.HandleRef, ma non implementa l'interfaccia System.IDisposable.
Descrizione della regola
Questa regola presuppone che nei campi IntPtr, UIntPtr e HandleRef siano archiviati puntatori a risorse non gestite. I tipi che allocano risorse non gestite devono implementare l'interfaccia IDisposable per consentire ai chiamanti di rilasciare quelle risorse su richiesta e di ridurre la durata degli oggetti che le contengono.
Il modello di progettazione consigliato per la pulitura delle risorse non gestite consiste nel fornire mezzi impliciti ed espliciti per liberare le risorse utilizzando rispettivamente il metodo Object.Finalize e il metodo IDisposable.Dispose. Il Garbage Collector chiama il metodo Finalize di un oggetto in un determinato momento dopo che l'oggetto è stato definito come non più raggiungibile. Dopo la chiamata al metodo Finalize, è necessaria un'operazione aggiuntiva di Garbage Collection per liberare l'oggetto. Il metodo Dispose consente al chiamante di rilasciare esplicitamente le risorse su richiesta, prima di quando verrebbero rilasciate dal Garbage Collector. Dopo aver eseguito la pulitura delle risorse non gestite, Dispose deve chiamare il metodo GC.SuppressFinalize per comunicare al Garbage Collector che non è più necessario chiamare il metodo Finalize. In questo modo, l'operazione di Garbage Collection aggiuntiva non è più necessaria e si riduce la durata dell'oggetto.
Correzione di violazioni
Per correggere una violazione di questa regola, implementare IDisposable.
Esclusione di avvisi
L'esclusione di un avviso da questa regola è sicura se il tipo non fa riferimento a una risorsa non gestita. In caso contrario, non escludere un avviso da questa regola poiché la mancata implementazione dell'interfaccia IDisposable può rendere non disponibili o sottoutilizzate le risorse non gestite.
Esempio
Nell'esempio riportato di seguito viene illustrato un tipo che implementa l'interfaccia IDisposable per eseguire la pulitura di una risorsa non gestita.
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);
}
}
}
Regole correlate
Chiamare GC.KeepAlive durante l'utilizzo di risorse native
Chiamare correttamente GC.SuppressFinalize
I tipi eliminabili devono dichiarare un finalizzatore
I tipi proprietari di campi Disposable devono essere Disposable
Vedere anche
Riferimenti
Implementazione dei metodi Finalize e Dispose per la pulitura delle risorse non gestite