Este artigo foi traduzido por máquina. Para visualizar o arquivo em inglês, marque a caixa de seleção Inglês. Você também pode exibir o texto Em inglês em uma janela pop-up, movendo o ponteiro do mouse sobre o texto.
Tradução
Inglês

Interface IDisposable

 

Publicado: agosto de 2016

Fornece um mecanismo para liberar recursos não gerenciados.

Para procurar o código-fonte do .NET Framework para este tipo, consulte o Reference Source.

Namespace:   System
Assembly:  mscorlib (em mscorlib.dll)

[ComVisibleAttribute(true)]
public interface IDisposable

NomeDescrição
System_CAPS_pubmethodDispose()

Realiza tarefas definidas pelo aplicativo associadas à liberação ou à redefinição de recursos não gerenciados.

System_CAPS_noteObservação

Para exibir o código-fonte do .NET Framework para este tipo, consulte o Reference Source. Percorra o código-fonte online, baixe a referência para exibição offline e percorrer as fontes (incluindo atualizações e patches) durante a depuração; see instructions.

O uso principal dessa interface é para liberar recursos não-gerenciados. O coletor de lixo automaticamente libera a memória alocada para um objeto gerenciado quando esse objeto não é mais usado. No entanto, não é possível prever quando ocorrerá a coleta de lixo. Além disso, o coletor de lixo não tem conhecimento de recursos não gerenciados, como identificadores de janela, ou abrir arquivos e fluxos.

Use o Dispose método desta interface explicitamente liberar recursos não gerenciados em conjunto com o coletor de lixo. O consumidor de um objeto pode chamar esse método quando o objeto não for mais necessário.

System_CAPS_warningAviso

É uma alteração significativa para adicionar o IDisposable interface para uma classe existente. Porque pré-existente consumidores do seu tipo não é possível chamar Dispose, você não pode ter certeza de que recursos não gerenciados mantidos pelo seu tipo serão lançados.

Porque o IDisposable.Dispose implementação é chamada pelo consumidor de um tipo quando os recursos pertencentes a uma instância não são mais necessários, ou você deve quebrar o objeto gerenciado em um SafeHandle (a alternativa recomendada), ou você deve substituir Object.Finalize para liberar recursos não gerenciados que o consumidor esquece de chamar Dispose.

System_CAPS_importantImportante

No .NET Framework, o compilador do C++ dá suporte à disposição determinística de recursos e não permite a implementação direta do Dispose método.

Para obter uma discussão detalhada sobre como essa interface e o Object.Finalize método são usadas, consulte o Coleta de Lixo e Implementando um método Dispose tópicos.

Implementar IDisposable somente se você estiver usando recursos não gerenciados diretamente. Se seu aplicativo simplesmente usa um objeto que implementa IDisposable, não fornecem um IDisposable implementação. Em vez disso, você deve chamar o objeto IDisposable.Dispose implementação quando tiver terminado de usá-lo. Dependendo da linguagem de programação, você pode fazer isso de duas maneiras:

  • Usando uma linguagem, como construir o using instrução em c# e Visual Basic.

  • Encapsulando a chamada para o IDisposable.Dispose implementação em um try/catch bloco.

System_CAPS_noteObservação

Documentação para tipos que implementam IDisposable Observe esse fato e incluir um lembrete para chamar sua Dispose implementação.

Se o seu idioma oferece suporte a uma construção, como o usando instrução em c# e o usando instrução no Visual Basic, você pode usá-lo em vez de chamar explicitamente IDisposable.Dispose por conta própria. O exemplo a seguir usa essa abordagem para definir um WordCount classe que preserva as informações sobre um arquivo e o número de palavras nele.

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

O using instrução é realmente uma conveniência sintática. Em tempo de compilação, o compilador de linguagem implementa a linguagem intermediária (IL) para um try/catch bloco.

Para obter mais informações sobre o using instrução, consulte o Instrução Using (Visual Basic) ou Instrução using (Referência de C#) tópicos.

Se a linguagem de programação não dá suporte a uma construção como o using instrução em c# ou Visual Basic, ou se você preferir não usá-lo, você pode chamar o IDisposable.Dispose implementação do finally block de um try/catch instrução. O exemplo a seguir substitui o using bloquear no exemplo anterior, com um try/catch/finally bloco.

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

Para obter mais informações sobre o try/finally padrão, consulte Instrução Try...Catch...Finally (Visual Basic), try-finally (Referência de C#), ou Instrução try-finally (C).

Você deve implementar IDisposable somente se o tipo usa recursos não gerenciados diretamente. Os consumidores de seu tipo podem chamar seu IDisposable.Dispose implementação para liberar recursos quando a instância não é mais necessário. Para lidar com casos em que eles não chamar Dispose, você deve usar uma classe derivada de SafeHandle incluir os recursos não gerenciados, ou você deve substituir o Object.Finalize método para um tipo de referência. Em ambos os casos, você deve usar o Dispose método para executar qualquer limpeza é necessária depois de usar os recursos não gerenciados, como à liberação ou redefinir os recursos não gerenciados.

System_CAPS_importantImportante

Se você estiver definindo uma classe base que usa recursos não gerenciados e que tem, ou deve ter subclasses que devem ser descartadas, você deve implementar o IDisposable.Dispose método e fornecer uma segunda sobrecarga de Dispose, conforme descrito na próxima seção.

Uma classe base com subclasses que devem ser descartáveis deve implementar IDisposable da seguinte maneira. Você deve usar esse padrão sempre que você implementar IDisposable em qualquer tipo que não seja sealed (NotInheritable no Visual Basic).

  • Ele deve fornecer um público, não virtual Dispose() um protegidos e método virtual Dispose(Boolean disposing) método.

  • O Dispose() método deve chamar Dispose(true) e deve suprimir a finalização de desempenho.

  • O tipo base não deve incluir qualquer finalizadores.

O fragmento de código a seguir reflete o padrão dispose para classes de base. Ele pressupõe que seu tipo não substitui o Object.Finalize método.

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

Se você substituir o Object.Finalize método, sua classe deve implementar o padrão a seguir.

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

As subclasses devem implementar o padrão descartável da seguinte maneira:

  • Eles devem substituir Dispose(Boolean) e chame a classe base Dispose(Boolean) implementação.

  • Eles podem fornecer um finalizador, se necessário. Deve chamar o finalizador Dispose(false).

Observe que as classes derivadas não se implementar a IDisposable interface e não incluem um sem parâmetros Dispose método. Eles apenas substituem a classe base Dispose(Boolean) método.

O fragmento de código a seguir reflete o padrão dispose para classes derivadas. Ele pressupõe que seu tipo não substitui o Object.Finalize método.

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

O exemplo a seguir demonstra como criar uma classe de recurso que implementa o 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.
    }
}

Plataforma Universal do Windows
Disponível desde 8
.NET Framework
Disponível desde 1.1
Biblioteca de Classes Portátil
Com suporte no: plataformas portáteis do .NET
Silverlight
Disponível desde 2.0
Windows Phone Silverlight
Disponível desde 7.0
Windows Phone
Disponível desde 8.1
Retornar ao início
Mostrar: