Condividi tramite


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

Altre risorse

Pulitura delle risorse non gestite