Compartilhar via


A implementação de finalização e Dispose para Limpar Unmanaged Recursos

ObservaçãoObservação:

Para obter informações sobre como finalização e eliminação usando o C++ , consulte Destruidores e Finalizers em Visual C++.

Instâncias da classe geralmente encapsulam o controle sobre recursos que não são gerenciado pelo tempo de execução, sistema autônomo identificadores de janela (HWND), conexões de banco de dados e assim por diante. Portanto, você deve fornecer um explícito e uma maneira implícita disponível esses recursos. Fornecer controle implícito ao implementar o protegido Finalize em um objeto (sintaxe do destruidor em translation from VPE for Csharp e C++). O coletor de lixo chama esse método em algum momento depois que não forem quaisquer referências ao objeto válidas.

Em alguns casos, convém fornecer os programadores que usam um objeto com a capacidade de liberar explicitamente esses recursos externos antes do coletor de lixo libera o objeto. Se um recurso externo for escassos ou dispendiosa, melhor desempenho pode ser obtido se o programador explicitamente libera recursos quando não estão sendo usados. Para fornecer controle explícito, implementar o Dispose fornecido pela IDisposable. O consumidor do objeto deve telefonar esse método quando ele for concluído usando o objeto. Descartar pode ser chamado, mesmo que outras referências ao objeto ativas.

Observe que, mesmo quando você fornecer controle explícito usando Descartar, você deve fornecer implícita limpeza usando o Finalizar método. Finalizar oferece um backup para evitar que recursos permanentemente vazando se o programador não chamar Descartar.

Para obter mais informações sobre como implementar Finalizar and Descartar para limpar recursos não gerenciados, consulte Coleta de Lixo. O exemplo de código a seguir ilustra o padrão de design básica para a implementação de Descartar . Este exemplo requer o System espaço para nome.

' Design pattern for a base class.

Public Class Base
   Implements IDisposable
    ' Field to handle multiple calls to Dispose gracefully.
    Dim disposed as Boolean = false

   ' Implement IDisposable.
   Public Overloads Sub Dispose() Implements IDisposable.Dispose
      Dispose(True)
      GC.SuppressFinalize(Me)
   End Sub

   Protected Overloads Overridable Sub Dispose(disposing As Boolean)
      If disposed = False Then
          If disposing Then
             ' Free other state (managed objects).
             disposed = True
          End If
      End If
      ' Free your own state (unmanaged objects).
      ' Set large fields to null.
   End Sub

   Protected Overrides Sub Finalize()
      ' Simply call Dispose(False).
      Dispose (False)
   End Sub
End Class

' Design pattern for a derived class.
Public Class Derived
   Inherits Base

    ' Field to handle multiple calls to Dispose gracefully.
    Dim disposed as Boolean = false

   Protected Overloads Overrides Sub Dispose(disposing As Boolean) 
      If disposed = False Then
          If disposing Then 
             ' Release managed resources.
             disposed = True
          End If
      End If
      ' Release unmanaged resources.
      ' Set large fields to null.
      ' Call Dispose on your base class.
      Mybase.Dispose(disposing)
   End Sub
   ' The derived class does not have a Finalize method
   ' or a Dispose method without parameters because it inherits
   ' them from the base class.
End Class
// Design pattern for a base class.
public class Base: IDisposable
{
   //Implement IDisposable.
   public void Dispose() 
   {
     Dispose(true);
      GC.SuppressFinalize(this); 
   }

   protected virtual void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
      // Set large fields to null.
   }

   // Use C# destructor syntax for finalization code.
   ~Base()
   {
      // Simply call Dispose(false).
      Dispose (false);
   }
}
// Design pattern for a derived class.
public class Derived: Base
{   
   protected override void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         // Release managed resources.
      }
      // Release unmanaged resources.
      // Set large fields to null.
      // Call Dispose on your base class.
      base.Dispose(disposing);
   }
   // The derived class does not have a Finalize method
   // or a Dispose method without parameters because it inherits
   // them from the base class.
}

Para obter um exemplo de código mais detalhado que ilustra o padrão de design para implementar Finalizar and Descartar, see Implementando um método Dispose.

Personalizando um nome do método Dispose

Ocasionalmente, um nome de domínio específico é mais apropriado do que Descartar. Por exemplo, um encapsulamento de arquivo conveniente usar o nome de método Fechar. Nesse caso, implementar Descartar em particular e criar um público Fechar método de chamaDescartar. O exemplo de código a seguir ilustra esse padrão. Você pode substituir Fechar com um nome de método apropriado para seu domínio. Este exemplo requer o System espaço para nome.

' Do not make this method overridable.
' A derived class should not be allowed
' to override this method.
Public Sub Close()
   ' Call the Dispose method with no parameters.
   Dispose()
End Sub
// Do not make this method virtual.
// A derived class should not be allowed
// to override this method.
public void Close()
{
   // Call the Dispose method with no parameters.
   Dispose();
}

Finalize 

As regras a seguir descrevem as diretrizes de uso para o Finalizar método:

  • Implementar Finalizar somente em objetos que necessitam de finalização. Há custos de desempenho associados Finalizar métodos.

  • Se você precisar de um Finalizar método, considere a implementação de IDisposable para permitir que os usuários de sua classe de evitar o custo de invocar o Finalizar método.

  • Não torne o Finalizarmétodo mais visível. Ele deve ser protegido, not pública.

  • Finalizar método deve liberar os recursos externos que possui o objeto. Além disso, um Finalizar método deve versão apenas recursos que o objeto ocupou até. The Finalizar método não deve fazer referência a quaisquer outros objetos.

  • Fazer telefonar não diretamente um Finalizar método em um objeto Outros que a classe base do objeto. Isso não é uma operação válida no translation from VPE for Csharp linguagem de programação.

  • telefonar the Finalizar da classe base método a partir de um objeto Finalizar método.

    ObservaçãoObservação:

    A classe base Finalizar método é chamado automaticamente com a sintaxe do destruidor translation from VPE for Csharp e C++.

Dispose

As regras a seguir descrevem as diretrizes de uso para o Descartar método:

  • Implemente o padrão de design de descarte em um tipo que encapsula recursos explicitamente precisam ser liberado. Os usuários podem disponível recursos externos, chamando o público Descartar método.

  • Implemente o padrão de design de descarte em um tipo de base que normalmente tem derivada tipos que Isenção os recursos, mesmo se o tipo base não. Se o tipo de base tem um Fechar método, geralmente, isso indica a necessidade de implementar Descartar. Em tais casos, não implementam um Finalizar método no tipo de base. Finalizar deve ser implementado em quaisquer tipos derivados que introduza recursos que exigem limpeza.

  • disponível quaisquer recursos descartáveis um tipo possui em sua Descartar método.

  • Depois de Descartar foi chamado em uma instância, evitar o Finalizar método de execução chamando o GC.SuppressFinalize. A exceção a essa regra é a situação rara em que o trabalho deve ser concluído em Finalizar que não é coberto por Descartar.

  • telefonar Descartar método se ele implementa IDisposable.

  • Não assuma que Descartar será chamado. Também devem ser liberados pertencentes a um tipo de recursos não gerenciados em um Finalizar método no evento que Descartar não é chamado.

  • Lançar um ObjectDisposedException de métodos de instância deste tipo (diferente de Descartar) Quando os recursos são já descartados. Esta regra não se aplica à Descartar método porque ela deve ser que pode ser chamada várias vezes sem gerar uma exceção.

  • Propagar os planos de Descartar pela hierarquia de tipos base. The Descartar método deve liberar todos os recursos mantidos por este objeto e qualquer objeto que pertence a este objeto. Por exemplo, você pode criar um objeto sistema autônomo um TextReader que mantiver um Stream e um Encoding, que são criados pela TextReader sem conhecimento do usuário. Além disso, a Stream e o Encoding pode adquirir recursos externos. Quando você liga o Descartar método a TextReader, ela deve chamar por sua vez Descartar on the Stream e o Encoding, fazendo com que eles liberar seus recursos externos.

  • Considere não permitir que um objeto a ser usado após sua Descartar método foi chamado. Recriar um objeto que já tinha sido descartado é um padrão difíceis de implementar.

  • Permitir que um Descartar método a ser chamado mais de uma vez sem gerar uma exceção. O método deve fazer nada após a primeira telefonar.

Partes direitos autorais 2005 Microsoft Corporation. Todos os direitos reservados.

Partes direitos autorais Addison-Wesley Corporation. Todos os direitos reservados.

Para obter mais informações sobre diretrizes de design, consulte a "diretrizes de design do estrutura: Catálogo de convenções, idiomas e padrões para bibliotecas do .NET reutilizável"Krzysztof Cwalina e Brad Abrams, publicado pela Addison-Wesley, 2005.

Consulte também

Referência

IDisposable.Dispose

Object.Finalize

Outros recursos

Diretrizes de Design para desenvolvimento bibliotecas de classe

Coleta de Lixo

Padrões de design