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

Código Fonte

O código fonte deste post pode ser baixado aqui.



Obrigado

Anúncios