Questa pagina è stata utile?
I suggerimenti relativi al contenuto di questa pagina sono importanti. Comunicaceli.
Altri suggerimenti?
1500 caratteri rimanenti
Esporta (0) Stampa
Espandi tutto
Il presente articolo è stato tradotto automaticamente. Passare il puntatore sulle frasi nell'articolo per visualizzare il testo originale. Ulteriori informazioni.
Traduzione
Originale

Interfaccia IDisposable

Fornisce un meccanismo per il rilascio delle risorse non gestite.

Spazio dei nomi:  System
Assembly:  mscorlib (in mscorlib.dll)

[ComVisibleAttribute(true)]
public interface IDisposable

Il tipo IDisposable espone i seguenti membri.

  NomeDescrizione
Metodo pubblicoSupportato da XNA FrameworkSupportato da Libreria di classi portabileSupportato in .NET per applicazioni Windows StoreDisposeEsegue attività definite dall'applicazione, ad esempio libera, rilascia o reimposta risorse non gestite.
In alto

Questa interfaccia viene utilizzata principalmente per rilasciare risorse non gestite. La memoria allocata a un oggetto gestito, nel momento in cui l'oggetto non è più in uso, viene rilasciata automaticamente dal Garbage Collector. Non è possibile prevedere quando si verificherà l'operazione di Garbage Collector. Il Garbage Collector non riceve inoltre informazioni su risorse non gestite, quali handle di finestra o file e flussi aperti.

Utilizzare il metodo Dispose insieme a Garbage Collector per rilasciare in modo esplicito risorse non gestite. Questo metodo può essere chiamato dal consumer di un oggetto quando l'oggetto non è più necessario.

Nota di avvisoAttenzione

Non aggiungere l'interfaccia di IDisposable a una classe esistente, poiché è ritenuta una modifica sostanziale.

Poiché l'implementazione di IDisposable.Dispose viene chiamata dal consumer di un tipo quando le risorse di proprietà da un'istanza non sono più necessari, è necessario o eseguire il wrapping dell'oggetto gestito in SafeHandle (l'alternativa consigliata), oppure è necessario eseguire l'override di Object.Finalize per liberare le risorse gestite nel caso in cui il consumer dimentichi di chiamare Dispose.

Nota importanteImportante

Ai programmatori C++ si consiglia di consultare distruttori e finalizzatori in Visual C++. In .NET Framework, il compilatore C++ supporta la disposizione deterministica le risorse e non consente l'implementazione diretta del metodo di Dispose.

Per una descrizione dettagliata dell'utilizzo di questa interfaccia e del metodo Object.Finalize, vedere gli argomenti Garbage Collection e Implementazione di un metodo Dispose.

Utilizzando un oggetto che implementa IDisposable

Implementare IDisposable solo se si utilizza direttamente le risorse non gestite. Se l'applicazione utilizza semplicemente un oggetto che implementa IDisposable, non fornire un'implementazione di IDisposable. Invece, è necessario chiamare l'implementazione di IDisposable.Dispose dell'oggetto al termine utilizzando. A seconda del linguaggio di programmazione, è possibile procedere in due modi:

  • Tramite un costrutto di linguaggio quali l'istruzione di using in c# e Visual Basic.

  • Eseguendo il wrapping della chiamata all'implementazione di IDisposable.Dispose in un bloccocatch / try.

NotaNota

Documentazione per i tipi che implementano la nota di IDisposable che il fatto che include una promemoria per chiamare l'implementazione di Dispose.

aax125c9.collapse_all(it-it,VS.110).gifC# e l'istruzione using di Visual Basic

Se i supporta un costrutto quale l'istruzione di using in c# e Visual Basic, è possibile utilizzarlo anziché in modo esplicito di chiamare IDisposable.Dispose manualmente. Nell'esempio seguente viene utilizzato questo approccio nella definizione della classe di WordCount che mantiene le informazioni su un file e il numero delle parole in.


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();
         sr.Close();
      }
      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; } }
}   


L'istruzione di using è effettivamente utile sintattica. In fase di compilazione, il compilatore di linguaggio implementa Microsoft Intermediate Language (IL) per un bloccocatch / try.

Per ulteriori informazioni sull'istruzione di using, vedere gli argomenti di Istruzione using (Riferimenti per C#) o di Istruzione Using (Visual Basic).

aax125c9.collapse_all(it-it,VS.110).gifIl blocco try/catch

Se il linguaggio di programmazione non supporta un costrutto quale l'istruzione di using in c# o Visual Basic, oppure se si preferisce non utilizzarlo, è possibile chiamare l'implementazione di IDisposable.Dispose dal blocco di finally di un'istruzionecatch / try. Nell'esempio sostituisce il blocco di using l'esempio precedente con try/catch/blocco difinally.


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();
         sr.Close();
      }
      catch {}
      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; } }
}   


Per ulteriori informazioni sul modelo try/finally, vedere Istruzione Try...Catch...Finally (Visual Basic), try...finally (Riferimenti per C#) o Istruzione try-finally (C).

Implementazione di IDisposable

Implementare IDisposable solo se il tipo utilizza direttamente le risorse non gestite. I consumer del tipo possono chiamare l'implementazione di IDisposable.Dispose per liberare risorse dell'istanza quando non è più necessario. Per gestire i casi in cui non riescono a chiamare Dispose, è necessario o utilizzare una classe derivata da SafeHandle per eseguire il wrapping delle risorse non gestite, o eseguire l'override del metodo di Object.Finalize per un tipo di riferimento. In entrambi i casi, si utilizza il metodo di Dispose per eseguire la pulizia è necessaria dopo l'utilizzo delle risorse non gestite, ad esempio liberare, il rilascio, o reimpostare le risorse non gestite.

Nota importanteImportante

Se si definisce una classe base che utilizza le risorse non gestite che abbiano, oppure è probabile per disporre, sottoclassi che devono essere eliminati, è necessario implementare il metodo di IDisposable.Dispose e fornire un secondo overload di Dispose, come descritto nella sezione successiva.

IDisposable e la gerarchia dell'ereditarietà

Una classe di base con sottoclassi eliminabili deve implementare IDisposable nel modo seguente:

  • Deve fornire un metodo Dispose() pubblico, non virtuale e un metodo Dispose(Boolean disposing) virtuale protetto.

  • Il metodo Dispose() deve chiamare Dispose(true) e deve eliminare la finalizzazione per le prestazioni.

  • Il tipo di base non deve includere alcun finalizzatori.

Nel frammento di codice riflette il modello dispose per tali classi. Si presuppone che il tipo non esegue l'override del metodo di Object.Finalize.


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


Se si esegue l'override del metodo di Object.Finalize, la classe deve implementare il modello seguente.


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


Le sottoclassi devono implementare il modello Disposable nel modo seguente:

  • Devono eseguire l'override di Dispose(Boolean) e chiamare l'implementazione Dispose(Boolean) della classe di base.

  • Se necessario, possono fornire un finalizzatore. Il finalizzatore deve chiamare Dispose(false).

Si noti che le classi derivate non fanno stesse implementano l'interfaccia di IDisposable e non includono un metodo senza parametri di Dispose. Sottoposta a override il metodo di Dispose(Boolean) della classe base.

Nel frammento di codice riflette il modello dispose per le classi derivate. Si presuppone che il tipo non esegue l'override del metodo di Object.Finalize.


using System;

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

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

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

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


Nell'esempio riportato di seguito viene illustrato come creare una classe di risorse che implementa l'interfaccia IDisposable.


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.
    }
}


.NET Framework

Supportato in: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supportato in: 4, 3.5 SP1

Libreria di classi portabile

Supportato in: Libreria di classi portabile

.NET per applicazioni Windows Store

Supportato in: Windows 8

.NET per applicazioni Windows Phone

Supportato in: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (ruoli di base del server non supportati), Windows Server 2008 R2 (ruoli di base del server supportati con SP1 o versione successiva, Itanium non supportato)

.NET Framework non supporta tutte le versioni di ciascuna piattaforma. Per un elenco delle versioni supportate, vedere Requisiti di sistema di .NET Framework.

Aggiunte alla community

AGGIUNGI
Mostra:
© 2015 Microsoft