Tento článek byl přeložený strojově. Pokud chcete zobrazit článek v angličtině, zaškrtněte políčko Angličtina. Anglickou verzi článku můžete také zobrazit v místním okně přesunutím ukazatele myši nad text.
Překlad
Angličtina

Rozhraní IDisposable

.NET Framework (current version)
 

Publikováno: srpen 2016

Poskytuje mechanismus pro uvolnění nespravovaných prostředků.

Chcete-li procházet zdrojový kód rozhraní .NET Framework pro tento typ, přečtěte si téma Reference Source.

Obor názvů:   System
Sestavení:  mscorlib (v mscorlib.dll)

[ComVisibleAttribute(true)]
public interface IDisposable

NázevPopis
System_CAPS_pubmethodDispose()

Provádí úkoly definované aplikací, které jsou přidružené k uvolnění, uvolnění nebo obnovení nespravovaných prostředků.

System_CAPS_notePoznámka

Chcete-li zobrazit zdrojový kód rozhraní .NET Framework pro tento typ, přečtěte si téma Reference Source. Můžete procházet zdrojový kód online, stáhněte odkaz pro zobrazení v režimu offline a projděte zdroje (včetně oprav a aktualizací) během ladění; see instructions.

Primárním použitím tohoto rozhraní je k uvolnění nespravovaných prostředků. Uvolňování paměti automaticky uvolní je paměť přidělená pro spravovaného objektu, pokud tento objekt se už používá. Není ale možné předpovědět, když dojde k uvolnění paměti. Kromě toho má systém uvolňování nezná nespravovaných prostředků, jako jsou popisovače oken nebo otevřít soubory a proudy.

Použití Dispose metody tohoto rozhraní explicitně uvolnění nespravovaných prostředků ve spojení s uvolňování paměti. Příjemce objekt můžete volat tuto metodu, pokud objekt již není potřeba.

System_CAPS_warningUpozornění

Je narušující změně přidat IDisposable rozhraní k existující třídě. Protože nelze volat existující příjemce vašeho typu Dispose, nemůže být určité zveřejníme nespravované prostředky držené vašeho typu.

Protože IDisposable.Dispose implementace je volána uživatelem typem, když už nejsou potřeba prostředků, které vlastní instance, má buď obtékat spravovaného objektu v SafeHandle (Doporučená alternativa), nebo by měly přepsat Object.Finalize na uvolnění nespravovaných prostředků v případě, že příjemci zapomene volat Dispose.

System_CAPS_importantDůležité

V rozhraní .NET Framework podporuje deterministický uvolnění prostředků C++ compiler a nedovolí přímé provádění Dispose Metoda.

Podrobné informace o tom, toto rozhraní a Object.Finalize Metoda se používá, najdete v článku Kolekce paměti a Implementace metody Dispose témata.

Implementace IDisposable pouze v případě, že používáte nespravované prostředky přímo. Pokud vaše aplikace používá jednoduše objekt, který implementuje IDisposable, neposkytují IDisposable implementace. Místo toho by měly volat objektu IDisposable.Dispose implementace po skončení jeho použití. V závislosti na vaší programovací jazyk můžete tento krok lze provést jedním ze dvou způsobů:

  • Pomocí jazyka vytvořit, jako using příkaz v C# a Visual Basic.

  • Nástrojem pro zabalení volání IDisposable.Dispose implementace v try/catch bloku.

System_CAPS_notePoznámka

Dokumentace pro typy, které implementují IDisposable Všimněte si, že fakt a zahrnout připomenutí volat jeho Dispose implementace.

Pokud váš jazyk podporuje konstrukt, jako pomocí příkaz v jazyce C# a pomocí příkaz v jazyce Visual Basic, můžete ji použít namísto výslovně volání IDisposable.Dispose sami. Následující příklad používá tento přístup k definování WordCount třídu, která uchovává informace o souboru a počet slov v ní.

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

using Příkaz je ve skutečnosti syntaktické pohodlí. Při kompilaci, kompilátor jazyka implementuje převodní jazyk (IL) pro try/catch bloku.

Další informace o using prohlášení, najdete v článku Using – příkaz (Visual Basic) nebo using – příkaz (Referenční dokumentace jazyka C#) témata.

Pokud si programovací jazyk nepodporuje konstrukt jako using příkaz v C# nebo Visual Basic, nebo pokud nechcete použít, můžete zavolat IDisposable.Dispose implementace z finally blokovat z trynebocatch příkaz. Nahrazuje následující příklad using Blokovat v předchozím příkladu s try/catch/finally bloku.

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

Další informace o trynebofinally vzor, najdete v části Try...Catch....Finally – příkaz (Visual Basic), try-finally (Referenční dokumentace jazyka C#), nebo try-finally – příkaz (C).

Měli byste implementovat IDisposable pouze v případě, že typ vašeho přímo používá nespravovaných prostředků. Uživatelé vašeho typu můžete volat vaše IDisposable.Dispose implementace kvůli uvolnění prostředků, pokud již nepotřebujete instance. Pro zpracování případy, ve kterých se nepodařilo volání Dispose, byste měli buď použijte třídu odvozenou z SafeHandle Zabalit nespravované prostředky, nebo by měly přepsat Object.Finalize metodu pro odkazového typu. V obou případech použijete Dispose metodu za účelem, ať čištění je nutné po použití nespravované prostředky, jako je například uvolnění uvolněním nebo resetováním nespravovaných prostředků.

System_CAPS_importantDůležité

Pokud definujete základní třídu používající nespravované prostředky a buď má, nebo může mít podtřídy, které by mělo být uvolněno, měli byste implementovat IDisposable.Dispose Metoda a poskytnout druhý přetížení Dispose, jak je popsáno v následující části.

Základní třída se měly podtřídy, které by měly být uvolnitelné musí implementovat IDisposable následujícím způsobem. Měli byste použít tento vzor vždy, když budete implementovat IDisposable na žádný typ, který není sealed (NotInheritable v jazyce Visual Basic).

  • Ho by měl poskytovat jeden public, bez virtuální Dispose() Metoda a s chráněným virtuální Dispose(Boolean disposing) Metoda.

  • Dispose() Musí volat metoda Dispose(true) a potlačit finalizace výkonu.

  • Základní typ nesmí obsahovat žádné finalizační metody.

Následující fragment kódu se vztahuje k uvolnění vzor pro základní třídy. Předpokládá, že typ vašeho nemůže přepsat Object.Finalize Metoda.

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

Pokud přepíšete Object.Finalize metodu, třídu by měla implementovat následující vzor.

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

Podtřídy by měla implementovat uvolnitelnou vzor následujícím způsobem:

  • Se musí přepsat Dispose(Boolean) a volat základní třídy Dispose(Boolean) implementace.

  • V případě potřeby mohli poskytnout finalizační metody. Finalizační metodu musí volat Dispose(false).

Všimněte si, že odvozené třídy sami neimplementují IDisposable rozhraní a nezahrnují bez parametrů Dispose Metoda. Pouze přednost před základní třídy Dispose(Boolean) Metoda.

Následující fragment kódu se vztahuje k uvolnění vzor odvozené třídy. Předpokládá, že typ vašeho nemůže přepsat Object.Finalize Metoda.

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

Následující příklad ukazuje, jak vytvořit Třída prostředků, který implementuje IDisposable rozhraní.

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

Univerzální platforma Windows
K dispozici od 8
.NET Framework
K dispozici od 1.1
Přenosná knihovna tříd
Podporováno v: přenosné platformy .NET
Silverlight
K dispozici od 2.0
Windows Phone Silverlight
K dispozici od 7.0
Windows Phone
K dispozici od 8.1
Zpět na začátek
Zobrazit: