C# - Usando Interfaces - II (IDisposable)
Vamos rever o conceito de Interfaces e mostrar como usar algumas interfaces importantes na linguagem C#. Hoje veremos a interface IDisposable. |
Continuando a primeira parte do artigo hoje veremos como usar a interface IDisposable.
A interface IDisposable fornece um mecanismo para liberar recursos não gerenciados.
O uso
principal dessa interface é para liberar recursos não-gerenciados. O coletor de
lixo automaticamente libera a memória alocada para um objeto gerenciado quando
esse objeto não é mais usado. No entanto, não é possível prever quando ocorrerá
a coleta de lixo. Além disso, o coletor de lixo não tem conhecimento de recursos
não gerenciados, como identificadores de janela, ou abrir arquivos e fluxos.
Usamos o método Dispose método desta interface para explicitamente
liberar recursos não gerenciados em conjunto com o coletor de lixo. O consumidor
de um objeto pode chamar esse método quando o objeto não for mais necessário.
Vejamos como usar essa interface na prática.
Recursos usados:
Usando a interface IDisposable
Neste primeiro exemplo vamos implementar o método Dispose da interface IDisposable para liberar recursos de um objeto não gerenciado.
Criando o projeto Console
Abra o VS 2017 Community e crie um novo projeto do tipo Console Application com o nome UsandoIDisposable
A seguir inclua uma classe chamada GerenciaArquivos no projeto com seguinte código :
using System;
using System.IO;
namespace UsandoIDisposable
{
class GerenciaArquivos : IDisposable
{
FileStream fs;
public GerenciaArquivos(string caminhoArquivo)
{
fs = new FileStream(caminhoArquivo, FileMode.OpenOrCreate, FileAccess.ReadWrite);
}
// Metodo para escrever os dados
public void Write(byte[] dados)
{
fs.Write(dados, 0, dados.Length);
}
// Implementando o método Dispose para liberar
// recursos não gerenciados pelo GC
public void Dispose()
{
fs.Close();
}
}
}
|
A classe GerenciaArquivos implementa a interface IDisposable e define o método Dispose onde faz o seguinte:
Agora vamos usar essa implementação incluindo o código abaixo no método Main() da classe Program :
using System.Text;
namespace UsandoIDisposable
{
class Program
{
static void Main(string[] args)
{
// Usando a instrução using
// o método Dipose() será chamado depois que
// a instrução for finalizada
using (GerenciaArquivos gerente = new GerenciaArquivos("teste.data"))
{
byte[] dados = Encoding.ASCII.GetBytes("Macoratti.net");
gerente.Write(dados);
}
}
}
}
|
Neste código criamos uma instância da classe GerenciarArquivos e usamos a instrução using que vai usar o método Dispose() implementado quando a instrução terminar.
Essa implementação é a mais simples possível. Vejamos agora uma implementação mais robusta.
Implementando IDisposable
Inclua um novo projeto na solução anterior chamado UsandoIDisposable2.
A seguir inclua a classe LogWriter que grava em um arquivo de log, no projeto:
using System;
using System.IO;
namespace UsandoIDisposable2
{
public class LogWriter
{
private StreamWriter m_Stream;
public LogWriter(string logFile)
{
m_Stream = new StreamWriter(logFile, true);
m_Stream.WriteLine("Iniciando o log às {0}", DateTime.Now);
}
public void WriteLine(string message)
{
m_Stream.WriteLine(message);
}
}
}
|
Neste código o StreamWriter criado no construtor da classe implementa a interface IDisposable, de forma que podemos chamar o seu método Dispose.
Vamos fazer isso implementando a interface IDisposable na classe LogWriter.
using System;
using System.IO;
namespace UsandoIDisposable2
{
public class LogWriter : IDisposable
{
private StreamWriter m_Stream;
public LogWriter(string logFile)
{
m_Stream = new StreamWriter(logFile, true);
m_Stream.WriteLine("Iniciando o log às {0}", DateTime.Now);
}
public void WriteLine(string message)
{
m_Stream.WriteLine(message);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// booleano
para controlar se
//
o método Dispose já foi chamado
private bool m_Disposed = false;
// método para controle
// da liberação dos recursos
protected virtual void Dispose(bool disposing) { if (!m_Disposed) { if (disposing) { m_Stream.Dispose(); } // Liberando recursos não gerenciados //informa que os recursos já foram liberados m_Disposed = true; } } ~LogWriter() { Dispose(false); } } } |
O método Dispose() definido pela interface IDisposable é um invólucro em torno de um método de protegido Dispose(bool disposing) que faz todo o trabalho. Primeiro, ele verifica uma flag para garantir que não estamos liberando o recurso duas vezes.
No método Dispose(), também há uma chamada para GC.SupressFinalize(this). Isso permitirá que o coletor de lixo libere a memória do objeto diretamente quando ele não estiver mais em uso.
Se omitimos esta chamada, o coletor de lixo terá que colocar o objeto no finalizador da classe, o método -LogWriter() , em vez de liberá-lo.
Uma vez que o finalizador foi executado (por uma thread em background), o objeto é elegível para coleta de lixo, mas não será coletado até o GC ser executado novamente.
Quando o finalizador é suprimido, o GC pode coletar o objeto na primeira execução.
Voce pode usar de forma bem simples:
using System;
namespace UsandoIDisposable2
{
class Program
{
static void Main(string[] args)
{
LogWriter log = new LogWriter("ArquivoLog.txt");
log.Dispose();
//ou
try
{
//codigo aqui
}
catch (Exception)
{
throw;
}
finally
{
log.Dispose();
}
}
}
}
|
Pegue o código do exemplo aqui : UsandoIDisposable.zip
(disse Jesus)
'Todavia digo-vos a verdade, que vos convém que eu vá;
porque, se eu não for, o Consolador não virá a vós; mas,
quando eu for, vo-lo enviarei.'
João 16:7
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
NET - Conhecendo um pouco mais sobre o Garbage ... - Macoratti.net