Ler em inglês

Compartilhar via


IDisposable.Dispose Método

Definição

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

C#
public void Dispose ();

Exemplos

O exemplo a seguir mostra como você pode implementar o Dispose método.

C#
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(disposing: true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SuppressFinalize 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# finalizer syntax for finalization code.
        // This finalizer will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide finalizer in types derived from this class.
        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(disposing: false) is optimal in terms of
            // readability and maintainability.
            Dispose(disposing: false);
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.
    }
}

Comentários

Use esse método para fechar ou liberar recursos não gerenciados, como arquivos, fluxos e identificadores mantidos por uma instância da classe que implementa essa interface. Por convenção, esse método é usado para todas as tarefas associadas à liberação de recursos mantidos por um objeto ou à preparação de um objeto para reutilização.

Aviso

Se você estiver usando uma classe que implementa a IDisposable interface, chame sua Dispose implementação quando terminar de usar a classe. Para obter mais informações, consulte a seção "Usando um objeto que implementa IDisposable" no IDisposable tópico.

Ao implementar esse método, verifique se todos os recursos mantidos são liberados propagando a chamada por meio da hierarquia de contenção. Por exemplo, se um objeto A alocar um objeto B e o objeto B alocar um objeto C, a implementação de Dispose A deverá chamar Dispose B, que deve, por sua vez, chamar Dispose C.

Importante

O compilador C++ dá suporte ao descarte determinístico de recursos e não permite a implementação direta do Dispose método.

Um objeto também deve chamar o Dispose método de sua classe base se a classe base implementar IDisposable. Para obter mais informações sobre a implementação IDisposable em uma classe base e suas subclasses, consulte a seção "IDisposable e a hierarquia de herança" no IDisposable tópico.

Se o método de Dispose um objeto for chamado mais de uma vez, o objeto deverá ignorar todas as chamadas após a primeira. O objeto não deve gerar uma exceção se seu Dispose método for chamado várias vezes. Métodos de instância diferentes do que Dispose podem gerar quando ObjectDisposedException os recursos já estão descartados.

Os usuários podem esperar que um tipo de recurso use uma convenção específica para indicar um estado alocado versus um estado liberado. Um exemplo disso são as classes de fluxo, que são tradicionalmente consideradas como abertas ou fechadas. O implementador de uma classe que tem essa convenção pode optar por implementar um método público com um nome personalizado, como Close, que chama o Dispose método.

Como o Dispose método deve ser chamado explicitamente, há sempre um perigo de que os recursos não gerenciados não sejam liberados, pois o consumidor de um objeto não chama seu Dispose método. Há duas maneiras de evitar isso:

  • Encapsular o recurso gerenciado em um objeto derivado de System.Runtime.InteropServices.SafeHandle. Em seguida, sua Dispose implementação chama o Dispose método das System.Runtime.InteropServices.SafeHandle instâncias. Para obter mais informações, consulte a seção "A alternativa SafeHandle" no Object.Finalize tópico.

  • Implemente um finalizador para liberar recursos quando Dispose não for chamado. Por padrão, o coletor de lixo chama automaticamente o finalizador de um objeto antes de recuperar sua memória. No entanto, se o Dispose método tiver sido chamado, normalmente será desnecessário que o coletor de lixo chame o finalizador do objeto descartado. Para evitar a finalização automática, Dispose as implementações podem chamar o GC.SuppressFinalize método.

Quando você usa um objeto que acessa recursos não gerenciados, como um StreamWriter, uma boa prática é criar a instância com uma using instrução. A using instrução fecha automaticamente o fluxo e chama Dispose o objeto quando o código que o está usando é concluído. Para obter um exemplo, consulte a StreamWriter classe.

Aplica-se a

Produto Versões
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Confira também