Cet article a fait l’objet d’une traduction automatique. Pour afficher l’article en anglais, activez la case d’option Anglais. Vous pouvez également afficher le texte anglais dans une fenêtre contextuelle en faisant glisser le pointeur de la souris sur le texte traduit.
Traduction
Anglais

IDisposable interface

 

Date de publication : novembre 2016

Fournit un mécanisme pour libérer des ressources non gérées.

Pour parcourir le code source de .NET Framework pour ce type, consultez la Reference Source.

Espace de noms:   System
Assembly:  mscorlib (dans mscorlib.dll)

[ComVisibleAttribute(true)]
public interface IDisposable

NomDescription
System_CAPS_pubmethodDispose()

Exécute les tâches définies par l'application associées à la libération ou à la redéfinition des ressources non managées.

System_CAPS_noteRemarque

Pour afficher le code source de .NET Framework pour ce type, consultez la Reference Source. Vous pouvez parcourir le code source en ligne, télécharger la référence de consultation hors connexion et parcourir les sources (y compris les correctifs et mises à jour) pendant le débogage ; see instructions.

La principale utilisation de cette interface est de libérer les ressources non managées. Le garbage collector libère automatiquement la mémoire allouée à un objet managé lorsque cet objet n’est plus utilisé. Toutefois, il n’est pas possible de prédire quand le garbage collection se produit. En outre, le garbage collector n’a aucune connaissance des ressources non managées, telles que les handles de fenêtre, ou ouvrir des fichiers et des flux de données.

Utilisez la Dispose méthode de cette interface pour libérer explicitement les ressources non managées en association avec le garbage collector. Le consommateur d’un objet peut appeler cette méthode lorsque l’objet n’est plus nécessaire.

System_CAPS_warningAvertissement

Il s’agit d’une modification avec rupture pour ajouter le IDisposable interface à une classe existante. Étant donné que les consommateurs existants de votre type ne peut pas appeler Dispose, vous n’êtes pas certain que les ressources non managées détenues par votre type seront libérés.

Étant donné que la IDisposable.Dispose implémentation est appelée par le consommateur d’un type lorsque les ressources détenues par une instance ne sont plus nécessaires, vous devez encapsuler soit l’objet managé dans un SafeHandle (l’alternative recommandée), ou vous devez substituer Object.Finalize pour libérer les ressources non managées dans le cas où le consommateur oublie d’appeler Dispose.

System_CAPS_importantImportant

Dans le .NET Framework, le compilateur C++ prend en charge la suppression déterministe de ressources et n’autorise pas l’implémentation directe de la Dispose (méthode).

Pour plus d’informations sur la façon de cette interface et la Object.Finalize méthode sont utilisées, consultez la Garbage Collection et Implémentation d'une méthode Dispose rubriques.

Implémentez IDisposable uniquement si vous utilisez directement des ressources non managées. Si votre application utilise simplement un objet qui implémente IDisposable, ne fournissent pas une IDisposable implémentation. Au lieu de cela, vous devez appeler l’objet IDisposable.Dispose implémentation lorsque vous avez fini de l’utiliser. Selon votre langage de programmation, vous pouvez faire de deux manières :

  • En utilisant un langage de construction tels que le using instruction en c# et Visual Basic.

  • En encapsulant l’appel à la IDisposable.Dispose mise en œuvre dans un try/catch bloc.

System_CAPS_noteRemarque

Documentation pour les types qui implémentent IDisposable Notez que les et inclure un rappel à appeler son Dispose implémentation.

Si votre langage prend en charge une construction tels que le à l’aide de instruction en c# et la Using instruction en Visual Basic, vous pouvez l’utiliser au lieu d’appeler explicitement IDisposable.Dispose vous-même. L’exemple suivant utilise cette approche dans la définition d’un WordCount classe qui conserve les informations sur un fichier et le nombre de mots qu’il contient.

using System;
using System.IO;
using System.Text.RegularExpressions;

public class WordCount
{
   private String filename = String.Empty;
   private int nWords = 0;
   private String pattern = @"\b\w+\b"; 

   public WordCount(string filename)
   {
      if (! File.Exists(filename))
         throw new FileNotFoundException("The file does not exist.");

      this.filename = filename;
      string txt = String.Empty;
      using (StreamReader sr = new StreamReader(filename)) {
         txt = sr.ReadToEnd();
      }
      nWords = Regex.Matches(txt, pattern).Count;
   }

   public string FullName
   { get { return filename; } }

   public string Name
   { get { return Path.GetFileName(filename); } }

   public int Count 
   { get { return nWords; } }
}   

La using instruction est réellement une commodité syntaxique. Au moment de la compilation, le compilateur de langage implémente le langage intermédiaire (IL) pour un try/catch bloc.

Pour plus d’informations sur la using instruction, consultez la Using Statement (Visual Basic) ou using, instruction (référence C#) rubriques.

Si votre langage de programmation ne prend pas en charge une construction comme le using instruction en c# ou Visual Basic, ou si vous préférez ne pas l’utiliser, vous pouvez appeler la IDisposable.Dispose implémentation à partir de la finally bloquer d’un try/catch instruction. L’exemple suivant remplace le using bloquer dans l’exemple précédent, avec un try/catch/finally bloc.

using System;
using System.IO;
using System.Text.RegularExpressions;

public class WordCount
{
   private String filename = String.Empty;
   private int nWords = 0;
   private String pattern = @"\b\w+\b"; 

   public WordCount(string filename)
   {
      if (! File.Exists(filename))
         throw new FileNotFoundException("The file does not exist.");

      this.filename = filename;
      string txt = String.Empty;
      StreamReader sr = null;
      try {
         sr = new StreamReader(filename);
         txt = sr.ReadToEnd();
      }
      finally {
         if (sr != null) sr.Dispose();     
      }
      nWords = Regex.Matches(txt, pattern).Count;
   }

   public string FullName
   { get { return filename; } }

   public string Name
   { get { return Path.GetFileName(filename); } }

   public int Count 
   { get { return nWords; } }
}   

Pour plus d’informations sur la try/finally de modèle, consultez Try...Catch...Finally Statement (Visual Basic), try-finally (référence C#), ou try-finally, instruction (C).

Vous devez implémenter IDisposable uniquement si votre type utilise directement les ressources non managées. Les consommateurs de votre type peuvent appeler votre IDisposable.Dispose implémentation de libérer des ressources lors de l’instance n’est plus nécessaire. Pour gérer les cas dans lesquels ils échouent à appeler Dispose, vous devez utiliser une classe dérivée de SafeHandle pour encapsuler les ressources non managées, ou vous devez substituer la Object.Finalize méthode pour un type référence. Dans les deux cas, vous utilisez la Dispose méthode pour effectuer le nettoyage est nécessaire après l’utilisation de ressources non managées, telles que la libération ou à la redéfinition des ressources non managées.

System_CAPS_importantImportant

Si vous définissez une classe de base qui utilise des ressources non managées et qui a, ou est susceptible d’avoir les sous-classes doivent être supprimés, vous devez implémenter la IDisposable.Dispose méthode et fournir une deuxième surcharge de Dispose, comme indiqué dans la section suivante.

Classe de base avec les sous-classes doivent être supprimables doit implémenter IDisposable comme suit. Vous devez utiliser ce modèle chaque fois que vous implémentez IDisposable sur n’importe quel type qui n’est pas sealed (NotInheritable en Visual Basic).

  • Elle doit fournir une méthode publique non virtuelle Dispose() et une méthode virtuelle protégée Dispose(Boolean disposing).

  • Le Dispose() méthode doit appeler Dispose(true) et doit supprimer la finalisation de performances.

  • Le type de base ne doit pas inclure de finaliseurs.

Le fragment de code suivant indique le modèle de suppression pour les classes de base. Il part du principe que votre type ne remplace pas le Object.Finalize (méthode).

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;
   // Instantiate a SafeHandle instance.
   SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         handle.Dispose();
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }
}

Si vous ne substituez pas la Object.Finalize (méthode), votre classe doit implémenter le modèle suivant.

using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   ~BaseClass()
   {
      Dispose(false);
   }
}

Les sous-classes doivent implémenter le modèle supprimable comme suit :

  • Elles doivent substituer Dispose(Boolean) et appeler l'implémentation Dispose(Boolean) de la classe de base.

  • Elles peuvent fournir un finaliseur, si nécessaire. Le finaliseur doit appeler Dispose(false).

Notez que les classes dérivées n’eux-mêmes implémentent pas la IDisposable interface et n’incluez pas un sans paramètre Dispose (méthode). Ils ne peuvent remplacer la classe de base Dispose(Boolean) (méthode).

Le fragment de code suivant indique le modèle de suppression pour les classes dérivées. Il part du principe que votre type ne remplace pas le Object.Finalize (méthode).

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;
   // Instantiate a SafeHandle instance.
   SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         handle.Dispose();
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //

      disposed = true;
      // Call base class implementation.
      base.Dispose(disposing);
   }
}

L’exemple suivant montre comment créer une classe de ressource qui implémente le IDisposable interface.

using System;
using System.ComponentModel;

// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.

public class DisposeExample
{
    // A base class that implements IDisposable.
    // By implementing IDisposable, you are announcing that
    // instances of this type allocate scarce resources.
    public class MyResource: IDisposable
    {
        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;

        // The class constructor.
        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        // Implement IDisposable.
        // Do not make this method virtual.
        // A derived class should not be able to override this method.
        public void Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        // Dispose(bool disposing) executes in two distinct scenarios.
        // If disposing equals true, the method has been called directly
        // or indirectly by a user's code. Managed and unmanaged resources
        // can be disposed.
        // If disposing equals false, the method has been called by the
        // runtime from inside the finalizer and you should not reference
        // other objects. Only unmanaged resources can be disposed.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if(!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }

                // Call the appropriate methods to clean up
                // unmanaged resources here.
                // If disposing is false,
                // only the following code is executed.
                CloseHandle(handle);
                handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;

            }
        }

        // Use interop to call the method necessary
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# destructor syntax for finalization code.
        // This destructor will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide destructors in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.
    }
}

Plateforme Windows universelle
Disponible depuis 8
.NET Framework
Disponible depuis 1.1
Bibliothèque de classes portable
Pris en charge dans : plateformes .NET portables
Silverlight
Disponible depuis 2.0
Silverlight pour Windows Phone
Disponible depuis 7.0
Windows Phone
Disponible depuis 8.1
Retour au début
Afficher: