Partager via


Les types qui possèdent des ressources natives doivent être supprimables

Mise à jour : novembre 2007

TypeName

TypesThatOwnNativeResourcesShouldBeDisposable

CheckId

CA1049

Catégorie

Microsoft.CSharp

Modification avec rupture

Modification sans rupture

Cause

Un type référence un champ System.IntPtr, System.UIntPtr ou System.Runtime.InteropServices.HandleRef, mais n'implémente aucun System.IDisposable.

Description de la règle

Cette règle suppose que les champs IntPtr, UIntPtr et HandleRef stockent des pointeurs vers des ressources non managées. Les types qui allouent des ressources non managées doivent implémenter IDisposable pour permettre aux appelants de libérer ces ressources à la demande et de raccourcir les durées de vie des objets qui les détiennent.

Le modèle de design recommandé pour nettoyer des ressources non managées consiste à fournir à la fois des moyens implicites et explicites de libérer ces ressources, respectivement à l'aide des méthodes Object.Finalize et IDisposable.Dispose. Le garbage collector appelle la méthode Finalize d'un objet à un moment indéterminé, après que l'objet a été déterminé comme désormais inaccessible. Après l'appel à Finalize, une opération garbage collection supplémentaire est nécessaire pour libérer l'objet. La méthode Dispose permet à l'appelant de libérer explicitement des ressources, et ce à la demande, avant le moment de leur libération si elles étaient laissées dans le garbage collector. Après avoir nettoyé les ressources non managées, Dispose doit appeler la méthode GC.SuppressFinalize pour permettre au garbage collector de déterminer que Finalize ne doit plus être appelée ; ce procédé élimine une opération garbage collection supplémentaire et raccourcit la durée de vie de l'objet.

Comment corriger les violations

Pour corriger une violation de cette règle, implémentez IDisposable.

Quand supprimer les avertissements

ll est possible de supprimer sans risque un avertissement de cette règle dès lors que le type ne référence aucune ressource non managée. Sinon, ne supprimez aucun avertissement de cette règle, sachant que l'échec de l'implémentation de IDisposable peut engendrer l'indisponibilité ou la sous-utilisation de ressources non managées.

Exemple

L'exemple suivant présente un type qui implémente IDisposable pour nettoyer une ressource non managée.

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

Règles connexes

Appelez GC.KeepAlive lorsque vous utilisez des ressources natives

Appeler GC.SuppressFinalize correctement

Les types pouvant être supprimés doivent déclarer un finaliseur

Les types possédant des champs pouvant être supprimés doivent être supprimables

Voir aussi

Référence

Implémentation des méthodes Finalize et Dispose pour nettoyer des ressources non managées

Autres ressources

Nettoyage de ressources non managées