Inicialização e encerramento de componentes

O componente é inicializado por seu construtor (Sub New em Visual Basic) e destruído pelo seu destruidor (Sub Finalizeem Visual Basic). O construtor do componente é chamado quando uma instância do seu componente é criada; o construtor não pode ser chamado a partir de então. O destruidor é chamado pouco antes de seu componente é destruído pelo coletor e sua memória é recuperada.

Observação sobre o Visual BasicObservação sobre o Visual Basic

Nas versões anteriores do Visual Basic, o Initialize e Terminate eventos servido a mesma finalidade que o construtor e destruidor.

Aguardando a coleta de lixo

O common language runtime chama o destruidor do componente após a coleta de lixo determina que o componente não pode ser acessado por qualquer código em execução. Isso ocorre se todas as referências ao componente foram lançadas ou somente referências ao seu componente são mantidas pelos objetos que estejam isolados da mesma forma de todo o código em execução — por exemplo, no caso de referências circulares.

Porque pode haver um atraso entre o momento quando um usuário é concluído com o componente e o momento em que quando seu destruidor é chamado, uma etapa adicional é introduzida na vida útil do.NET Framework disponíveis: Se o seu componente adquire os recursos de sistema, como, por exemplo, conexões de banco de dados ou as alças de objetos do sistema do Windows, você deve implementar a IDisposable interface e fornecer um Dispose método para que os usuários do seu componente podem escolher quando deseja liberar esses recursos.

Ciclo de vida de um componente

Digite inicialização: Quando a primeira instância do seu componente é criada, o primeiro código que executa é qualquer código de inicialização compartilhados. Uma referência a qualquer membro compartilhado também fará com que o construtor compartilhado executar. Isso inclui qualquer compartilhado campos (variáveis de membro) que são inicializados e o construtor compartilhado (Shared Sub New) se ele existir. No código a seguir, uma fonte de referência é criada para toda a turma.

ObservaçãoObservação

A palavra-C# chave que corresponde a Shared é static, que não deve ser confundido com o Static palavra-chave em Visual Basic.

Public Class ADrawing
Shared ReadOnly ReferenceFont As New Font("TimesNewRoman", 14)
' Shared constructor does not overload other constructors.
Shared Sub New()
   ' There is no call to the base class's shared constructor.
   ' Insert code to initialize the shared data.
End Sub
End Class
class ADrawing
{
   static Font m_referenceFont = new Font("TimesNewRoman", 14);
   // Simply add the static keyword to create a static constructor.
   // Static constructors do not have any parameters.
   static ADrawing()
   {
      // There is no call to the base class's static constructor.
      // Code to initialize the font here.
   }
}
ObservaçãoObservação

Inicialização da classe pode ocorrer mesmo se não há instâncias do seu componente são criadas. Por exemplo, um abstract (MustInherit) a classe com funções de membro compartilhado será inicializada e essas funções estarão disponíveis para uso pelo aplicativo, mesmo que nenhuma instância da classe é criada.

  1. Inicialização de instância: Quando uma instância do seu componente é criada, os membros de dados que possuem o código de inicialização são inicializados e a sobrecarga do construtor apropriado é executada. O código a seguir inicializa um campo privado e define dois construtores, um para ser chamado se não houver nenhum parâmetro e o outro para ser chamado se o usuário Especifica os parâmetros.

    Class AShape
       Private answer As Integer = 42
       Public Sub New()
          ' Call another constructor with default initialization values.
          MyClass.New(System.Drawing.Color.Red, 5280, DefinedSizes.Large)
       End Sub
       Public Overloads Sub New(myColor As Color, myLength As Integer, _
                Size As DefinedSizes)
          ' Insert code to initialize the class.
       End Sub
       ' Defines the DefinedSizes enum
       Public Enum DefinedSizes
          Large
          Small
       End Enum
    End Class
    
    class AShape
    {
       private int m_answer = 42;
       // Forward to another constructor.
       public AShape() 
       : this(System.Drawing.Color.Red, 5280, DefinedSizes.Large)
       {
          // Additional initialization goes here.
       }
    
       public AShape(Color color, int length, DefinedSizes size)
       {
          // Code to initialize the class goes here.
       }
       // Defines the DefinedSizes enum
       public enum DefinedSizes
       {
          Large,
          Small
       }
    }
    
  2. Descarte de recursos: Se seu componente implementa o IDisposable interface, ele deverá fornecer um Dispose método, que o cliente deve chamar quando ele for concluído usando o componente. Observe que qualquer componente que herda de Component já tem uma implementação padrão de Dispose, que pode ser substituído para fornecer o código de limpeza adicional. No Dispose método, o seu componente libera todos os recursos de sistema podem ter alocados, libera as referências a outros objetos e inutiliza propriamente dito. Também pode haver instâncias onde é apropriado para seu componente chamar o seu próprio Dispose método. O código a seguir descarta de um objeto dependente que tem um Dispose método.

    ' Assumes that the class implements IDisposable
    Public Sub Dispose() Implements IDisposable.Dispose
       myWidget.Dispose
       myWidget = Nothing
       ' Insert additional code.
    End Sub
    
    // Assumes that the class implements IDisposable
    public void IDisposable.Dispose()
    {
       mywidget.Dispose();
       mywidget = null;
       // Dispose of remaining objects.
    }
    
    

    Depois de chamar Dispose, o cliente deve liberar qualquer referências restantes para o componente para que a coleta de lixo pode recuperar de memória. o componente

  3. Destruição de instância: Quando a coleta de lixo detecta que não há nenhum referências restantes para o componente, o tempo de execução chama o destruidor do componente (Finalizeem Visual Basic) e libera a memória. Você deve substituir sua classe base Finalize método (Visual Basic) ou implementar um destruidor (para Visual C#) para implementar seu próprio código de limpeza, mas sempre incluir uma chamada para o destruidor ou Finalize o método da classe de base.

    Protected Overrides Sub Finalize()
       m_Gadget = Nothing
       m_Gear = Nothing
       MyBase.Finalize()
    End Sub
    
    // In C#, a destructor is used instead of a Finalize method.
    ~ThisClass()
    {
       m_gadget = null;
       m_gear = null;
       // The base class finalizer is called automatically
    }
    

Quando você deve implementar um método Dispose?

Se o seu componente herda de Component, uma implementação padrão de Dispose é fornecido. Essa implementação pode ser substituída para fornecer o código de limpeza personalizada. Se você estiver criando o seu componente por meio da criação de uma implementação personalizada do IComponent, você deve implementar IDisposable para fornecer uma Dispose método para seu componente.

Seu componente precisar um Dispose método se ele aloca objetos do sistema, conexões de banco de dados ou outros recursos escassos, que devem ser liberados assim que um usuário for concluído com o componente.

Você também deve implementar um Dispose método se o seu componente contém referências a outros objetos que tenham Dispose métodos.

Por que implementar Dispose?

Dependendo da atividade do sistema, um intervalo imprevisível pode decorrer entre o momento em que um usuário termina de usar o seu componente e a coleta de lixo do tempo detecta que o código do componente é inalcançável. Se você não fornecer um Dispose método, o seu componente continuará manter seus recursos durante este intervalo.

Um cenário mais desfavorável

Imagine um componente de servidor que usa uma conexão de banco de dados e não tem um Dispose método. Em um servidor com uma grande quantidade de memória, você pode criar e lançar muitas instâncias do componente sem ter muito impacto na memória livre. Nesse caso, a coleta de lixo não pode destruir os componentes por algum tempo depois que as referências a eles são lançadas.

Eventualmente, todas as conexões de banco de dados disponíveis poderiam ser amarradas por componentes que tinham sido liberados, mas não destruídos. Mesmo que o servidor não tivesse nenhuma falta de memória, pode ser incapaz de responder às solicitações do usuário.

Consulte também

Tarefas

Como: Criar e configurar componentes no modo de Design

Referência

Dispose

Finalize

Conceitos

Características da classe de componente

Alterações na Visual Basic de instanciação de componente