A interface IDisposable é usada para liberar recursos. O garbage collector (coletor de lixo) libera automaticamente a memória alocada para um objeto gerenciado quando este objeto não estiver mais sendo utilizado. No entanto, não é possível prever quando esta coleta de lixo irá ocorrer. Além disso, o garbage collector não tem conhecimento dos recursos não gerenciados.
Usamos o método Dispose desta interface para liberar explicitamente recursos não gerenciados em conjunto com o garbage collector. O consumidor de um objeto pode chamar esse método quando o objeto não for mais necessário.
Inicialmente, precisamos fazer a classe que queremos implementar IDisposable herdar desta interface.
// C#
public class GerenciarClientes : IDisposable
{
public void Dispose()
{
}
}
' VB.NET
Public Class GerenciarClientes
Implements IDisposable
Public Overridable Sub Dispose() Implements IDisposable.Dispose
End Sub
End Class
OBS: Em C#, para que o próprio Visual Studio implemente o método Dispose, basta clicar com o botão direito do mouse sobre a interface, escolher a opção ‘Implement Interface’ e ‘Implement Interface’ novamente. Esse mesmo procedimento funciona com a implementação de qualquer interface em uma classe.
Para controlarmos corretamente a liberação dos recursos, é necessário criar uma variável do tipo booleana, que indicará se o método Dispose já foi disparado.
Além disso, precisamos criar um método privado que será chamado de lugares distintos e controlará quais recursos (gerenciados ou não) devem ser liberados.
// C#
// booleano para controlar se
// o método Dispose já foi chamado
bool disposed = false;
// método privado para controle
// da liberação dos recursos
private void Dispose(bool disposing)
{
// Verifique se Dispose já foi chamado.
if (!this.disposed)
{
if (disposing)
{
// Liberando recursos gerenciados
}
// Seta a variável booleana para true,
// indicando que os recursos já foram liberados
disposed = true;
}
}
' VB.NET
' booleano para controlar se
' o método Dispose já foi chamado
Private disposed As Boolean = False
' método privado para controle
' da liberação dos recursos
Private Sub Dispose(ByVal disposing As Boolean)
' Verifique se Dispose já foi chamado.
If Not Me.disposed Then
If disposing Then
' Liberando recursos gerenciados
End If
' Seta a variável booleana para true,
' indicando que os recursos já foram liberados
disposed = True
End If
End Sub
Dentro do método público Dispose, é necessário chamar o método privado Dispose e também informar o garbage collector para não chamar o método finalizador da classe, pois estamos controlando isso manualmente. Para isto, utilizamos o método GC.SuppressFinalize().
// C#
bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
' VB.NET
Dim disposed As Boolean = False
Protected Overridable Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Por fim, precisamos programar o método finalizador da classe, que é invocado pelo garbage collector para liberar os recursos. Toda liberacao implementada dentro dele só será executada quando o metodo for invocado, porém não conseguimos saber quando isto vai acontecer e recursos importantes podem ficar presos até que isto aconteça.
// C#
~GerenciarClientes()
{
Dispose(false);
}
' VB.NET
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
Pronto, implementamos IDisposable. Com essa implementação, sempre que tivermos uma instância da classe que não será mais utilizada, devemos chamar o método Dispose ou envolvê-la em um bloco using.
// C#
// forma simples
GerenciarClientes g1 = new GerenciarClientes();
// código consumidor da instância
// Liberando o recurso
g1.Dispose();
// usando try...finally
GerenciarClientes g2 = new GerenciarClientes();
try
{
// código consumidor da instância
}
finally
{
g2.Dispose();
}
// ou com using
using (GerenciarClientes g3 = new GerenciarClientes())
{
// código consumidor da instância
} // aqui o método Dispose é invocado
' VB.NET
' forma simples
Dim g1 As New GerenciarClientes()
' código consumidor da instância
' Liberando o recurso
g1.Dispose()
' usando Try...Finally
Dim g2 As New GerenciarClientes()
Try
' código consumidor da instância
Finally
g2.Dispose()
End Try
' ou com using
Using g3 As New GerenciarClientes()
' código consumidor da instância
End Using ' aqui o método Dispose é invocado
Referências
- Interface IDisposable
- Método GC.SuppressFinalize
- Garbage Collector
- Método IDisposable.Dispose
- Liberando os objetos de forma apropriada
Código Fonte
O código fonte deste post pode ser baixado aqui.
Obrigado




