No artigo, Coding New Instances of Objects, escrevi sobre as várias maneiras pelas quais Novo instâncias de objetos podem ser criadas. O problema oposto, a disposição de um objeto, é algo com o qual você não precisará se preocupar com frequência no VB.NET. O .NET inclui uma tecnologia chamada Coletor de lixo (GC) que geralmente cuida de tudo nos bastidores de maneira silenciosa e eficiente. Mas, ocasionalmente, geralmente ao usar fluxos de arquivos, objetos sql ou objetos gráficos (GDI +) (ou seja, recursos não gerenciados), pode ser necessário controlar o descarte de objetos em seu próprio código.
Primeiro, alguns antecedentes
Assim como um vigaristaestruturador (o Novo palavra-chave) cria um novo objeto, uma destructor é um método chamado quando um objeto é destruído. Mas há um problema. As pessoas que criaram o .NET perceberam que era uma fórmula para erros se duas partes diferentes do código pudessem realmente destruir um objeto. Portanto, o .NET GC está realmente no controle e geralmente é o único código que pode destruir a instância do objeto. O GC destrói um objeto quando decide e não antes. Normalmente, depois que um objeto sai do escopo, é
liberado pelo Common Language Runtime (CLR). O GC destrói objetos quando o CLR precisa de mais memória livre. Portanto, o ponto principal é que você não pode prever quando o GC realmente destruirá o objeto.(Welllll... Isso é verdade por pouco todo o tempo. Você pode ligar GC.Collect e forçar um ciclo de coleta de lixo, mas as autoridades dizem universalmente que é um mau idéia e totalmente desnecessário.)
Por exemplo, se o seu código criou um Cliente objeto, pode parecer que esse código o destruirá novamente.
Cliente = Nada
Mas isso não acontece. (Definir um objeto como Nothing é comumente chamado, desreferenciamento o objeto.) Na verdade, significa apenas que a variável não está mais associada a um objeto. Algum tempo depois, o GC notará que o objeto está disponível para destruição.
A propósito, para objetos gerenciados, nada disso é realmente necessário. Embora um objeto como um Button ofereça um método Dispose, não é necessário usá-lo e poucas pessoas o fazem. Os componentes do Windows Forms, por exemplo, são adicionados a um objeto de contêiner chamado componentes. Quando você fecha um formulário, seu método Dispose é chamado automaticamente. Normalmente, você só precisa se preocupar com isso ao usar objetos não gerenciados e, mesmo assim, apenas para otimizar seu programa.
A maneira recomendada de liberar qualquer recurso que possa ser mantido por um objeto é chamar o Descarte método para o objeto (se houver um disponível) e desreferencie o objeto.
Cliente. Dispose () Cliente = Nada
Como o GC destruirá um objeto órfão, independentemente de você definir ou não a variável de objeto como Nothing, não é realmente necessário.
Outra maneira recomendada de garantir que os objetos sejam destruídos quando não forem mais necessários é colocar o código que usa um objeto em um Usando quadra. Um bloco Using garante o descarte de um ou mais desses recursos quando seu código é finalizado com eles.
Na série GDI +, o Usando O bloco é usado com bastante frequência para gerenciar esses objetos gráficos incômodos. Por exemplo ...
Usando o myBrush como LinearGradientBrush _. = Novo LinearGradientBrush (_. Eu. ClientRectangle, _. Cor. Cor azul. Vermelho, _. LinearGradientMode. Horizontal) <... mais c ...> Terminar usando
myBrush é descartado automaticamente quando o final do bloco é executado.
A abordagem do GC para gerenciar memória é uma grande mudança em relação à maneira como o VB6 fez isso. Objetos COM (usados pelo VB6) foram destruídos quando um contador interno de referências atingiu zero. Como era muito fácil cometer um erro, o contador interno estava desligado. (Como a memória estava amarrada e não estava disponível para outros objetos quando isso aconteceu, isso foi chamado de "vazamento de memória".) Em vez disso, o GC realmente verifica se algo está fazendo referência a um objeto e o destrói quando não há mais referências. A abordagem do GC tem um bom histórico em linguagens como Java e é uma das grandes melhorias no .NET.
Na próxima página, veremos a interface IDisposable... a interface a ser usada quando você precisar Dispor objetos não gerenciados em seu próprio código.
Se você codificar seu próprio objeto que utiliza recursos não gerenciados, use o método IDisposable interface para o objeto. A Microsoft facilita isso, incluindo um trecho de código que cria o padrão certo para você.
Clique aqui para exibir a ilustração
Clique no botão Voltar no seu navegador para retornar
O código adicionado é semelhante a este (VB.NET 2008):
Classe ResourceClass. Implementa IDisposable. 'Para detectar chamadas redundantes. Particularmente descartado Como Booleano = Falso. 'IDisposable. Substituir Substituível Protegido (_. ByVal descartando como booleano) Se não for Me.disposed Then. Se descartar Então. 'Livre outro estado (objetos gerenciados). Fim se. 'Liberte seu próprio estado (objetos não gerenciados). 'Defina campos grandes como nulos. Fim se. Me.disposed = Verdadeiro. End Sub. #Region "IDisposable Support" 'Este código adicionado pelo Visual Basic a. 'implementar corretamente o padrão descartável. Public Sub Dispose () Implementa IDisposable. Descarte. 'Não mude este código. 'Coloque o código de limpeza. 'Descarte (ByVal descartando como booleano) acima. Dispose (True) GC.SuppressFinalize (Me) End Sub. Substituições protegidas Sub Finalize () 'Não altere este código. 'Coloque o código de limpeza. 'Descarte (ByVal descartando como booleano) acima. Descarte (False) MyBase. Finalize () End Sub. # End Region. Classe final
Descarte é quase um padrão de design de desenvolvedor "imposto" no .NET. Existe realmente apenas uma maneira correta de fazer isso e é isso. Você pode pensar que esse código faz algo mágico. Não faz.
Primeira nota que a bandeira interna disposto simplesmente curto-circuito a coisa toda para que você possa ligar Descarte (descarte) quantas vezes você quiser.
O código ...
GC.SuppressFinalize (Me)
... torna seu código mais eficiente informando ao GC que o objeto já foi descartado (uma operação 'cara' em termos de ciclos de execução). Finalizar está protegido porque o GC o chama automaticamente quando um objeto é destruído. Você nunca deve ligar para Finalizar. O Booleano disposição informa ao código se o seu código iniciou o descarte do objeto (True) ou se o GC o fez (como parte do Finalizar sub. Observe que o único código que usa o valor booleano disposição é:
Se descartar Então. 'Livre outro estado (objetos gerenciados). Fim se
Quando você descarta um objeto, todos os seus recursos devem ser descartados. Quando o CLR coletor de lixo descarta um objeto apenas os recursos não gerenciados devem ser descartados porque o coletor de lixo cuida automaticamente dos recursos gerenciados.
A idéia por trás desse snippet de código é que você adicione código para cuidar de objetos gerenciados e não gerenciados nos locais indicados.
Quando você obtém uma classe de um classe base que implementa o IDisposable, você não precisa substituir nenhum dos métodos básicos, a menos que use outros recursos que também precisam ser descartados. Se isso acontecer, a classe derivada deve substituir o método Dispose (descarte) da classe base para descartar os recursos da classe derivada. Mas lembre-se de chamar o método Dispose (descarte) da classe base.
Substituições protegidas SubDispose (ByVal descartando como booleano) Se não for Me.disposed Then. Se descartar Então. 'Adicione seu código para liberar recursos gerenciados. Fim se. 'Adicione seu código para liberar recursos não gerenciados. Fim se. MyBase. Descarte (descarte) End Sub
O assunto pode ser um pouco avassalador. O objetivo da explicação aqui é "desmistificar" o que realmente está acontecendo, porque a maioria das informações que você pode encontrar não informa!