uniPaaS 2.0 – Detalhes que fazem a diferença – 02

Manoel Frederico da Silva / Product Manager & MAGIC Evangelist / Magic Software Brasil

Falamos anteriormente (ver aqui) a respeito de alguns cuidados necessários ao utilizar classes MS.NET em nossas soluções baseadas no novo uniPaaS 2.0.

Vamos agora abordar mais um, bastante importante.

O MS.NET, assim como o Java, é um ambiente gerenciado automaticamente. Resumindo: ele cuida de toda a alocação e liberação de recursos (ex: memória) necessários ao programa, de forma automática e nos bastidores.

Mas, ao menos no MS.NET, o desenvolvedor não está 100% livre de se preocupar com estas coisas.

Algumas classes .NET implementam a interface IDispose. Quando uma classe implementa “IDispose”, ela está dizendo ao desenvolvedor que, internamente, ela faz uso de recursos do sistema operacional (normalmente não gerenciados) que são escassos ou compartilhados, e precisam ser utilizados com prudência e liberados (devolvidos ao sistema operacional) assim que não forem mais necessários. Por exemplo: conexões com bases de dados, sockets, arquivos abertos, etc…

“…

Certa vez tivemos de enviar mensagens (e-mails) através do MS.NET, e verificou-se que os arquivos enviados como anexo permaneciam inacessíveis (sem poder ser lido por mais ninguém) até que o programa .NET fosse encerrado. Isso era porque faltava realizar o Dispose() do objeto “mensagem” que mantinha aberto os arquivos anexados

…”

Este tipo de classe .NET possui um método chamado Dispose() que deve ser chamado “manualmente” pelo desenvolvedor, assim que ele entender que objeto não será mais usado em seu programa. Do contrário, o recurso ficará “preso” até que o framework MS.NET decida que é hora de liberar o objeto da memória.

Caso você queira estudar mais sobre o “Dispose/Finalize Pattern”, há bastante material disponível na internet sobre isso (como aqui).

Mas o que isso tem a ver com meus programas uniPaaS?

Depende do tipo de classe que você utilizar na sua aplicação.

Vamos tomar como exemplo a classe .NETFileStream”. Podemos utilizá-la para fazer leitura/gravação de arquivos binários. Veja:

Quando instanciamos um objeto da classe “FileStream”, temos ativo (na memória) um objeto .NET que internamente está alocando recursos não gerenciados (neste caso, um “handle” para o arquivo aberto/criado):

Quando a tarefa uniPaaS que criou o objeto finalizar, este objeto será considerado “out of scope” pelo MS.NET e liberado em algum momento (segundo as regras do GC). Pode ser em seguida, ou pode demorar um pouco.

E se tivermos aberto um arquivo em modo exclusivo? Enquanto o objeto não for efetivamente liberado pelo MS.NET, este arquivo ficará bloqueado a qualquer outro usuário ou processo.

Por isso, devido a natureza “não determinista” do GC MS.NET, é prudente que venhamos a liberar este recurso não gerenciado assim que terminar de utilizarmos o objeto (quando ele não for mais necessário):

Não dá para saber visualmente, se uma classe .NET implementa ou não a IDispose. É preciso recorrer a documentação da classe, ou pelo menos listar seus métodos públicos e ver se há algum chamado Dispose().

Para encerrar: algumas dessas classes .NET (como é o caso de FileStream) possui também um método chamado Close(), que faz o mesmo serviço que o Dispose(). Isso ocorre apenas por questões de legibilidade, já que faz mais sentido “fechar” um arquivo que foi aberto, do que “descartá-lo”. Por isso, a instrução a seguir também seria correta neste caso:

Deixe um comentário

O seu endereço de e-mail não será publicado.