Arquitetura Corporativa para Todos

Artigo / Post

Dispose assíncrono, conheça as vantagens e precauções e como utilizá-lo

Antes vamos revisar rapidamente alguns conceitos antes de discutir o método dispose assíncrono.

Por que os métodos Dispose e Finalize existem?

O .NET é um ambiente gerenciado, ou seja, ele é responsável por alocar e liberar memória e gerenciar o tempo de vida dos objetos que ele cria.  Mas o que acontece quando esses objetos estão sob o domínio e controle do sistema operacional (os famosos objetos não gerenciados, como arquivos, portas, rede e outros)? É aí que entram os métodos Dispose e Finalize, que fazem uma “ponte” entre esses dois ambientes, possibilitando o gerenciamento desses recursos.

O método Dispose é usado para liberar explicitamente (por meio de código) os recursos (não gerenciados) antes que o ambiente libere o objeto.

O método Finalize, por outro lado, é chamado implícita e não deterministicamente pelo ambiente gerenciado para liberar esse recurso alocado na memória durante ou ao final da execução do aplicativo.

Ambos os métodos visam informar ao sistema operacional qual recurso não gerenciado alocado na memória precisa ser liberado. Em resumo, você controla quando e onde usar o método Dispose , enquanto não controla o método Finalize ; somente o ambiente pode chamá-lo diretamente, e ele tem um “custo” muito maior para sua aplicação em termos de desempenho e gerenciamento de memória dependendo do cenário. As melhores maneiras de usá-los e os detalhes das diferenças entre eles e outras características e comportamentos não são o foco do tópico que estamos apresentando.

Por que o método Dispose assíncrono foi criado?

Conforme explicado anteriormente, Dispose é usado para liberar explicitamente (por meio de código) os recursos (não gerenciados).  Para esta execução de release, que é feita de forma síncrona , é necessário interromper o thread de execução atual para que o ambiente gerenciado “converse” com o sistema operacional e aguarde a execução das tarefas de release e retorne para que o aplicativo continue sua tarefa.

Essa jornada de execução síncrona não é vantajosa para aplicativos e linguagens mais modernos que fazem uso de vários núcleos de processador disponíveis.  Com isso em mente, a possibilidade de usar a interface IAsyncDisposable foi introduzida como parte do C# 8.0 (setembro de 2019!) para permitir o descarte assíncrono de recursos não gerenciados.

Além dessa melhoria, ao longo do tempo, diversas outras melhorias foram feitas no .NET CORE para permitir operações assíncronas, adaptando o ecossistema como um todo para aproveitar eficientemente os recursos de múltiplos núcleos de processadores, o que chamamos de multithreading e processamento “paralelo”.

Principais vantagens do Dispose assíncrono

  • Maior desempenho: operações assíncronas permitem que o sistema continue executando outras tarefas enquanto aguarda a conclusão do descarte, resultando em uso mais eficiente de recursos.
  • Melhor escalabilidade: aplicativos que usam descarte assíncrono podem lidar com mais solicitações simultâneas, tornando-se mais escaláveis.
  • Redução de bloqueios: como as operações não precisam esperar umas pelas outras, há menos bloqueios e gargalos no sistema.

Benefício em um cenário típico

Todos os serviços registrados como Scoped (ou seja, que só existem durante a solicitação HTTP atual) que implementam IAsyncDisposable serão descartados de forma assíncrona no final da solicitação, liberando tempo e recursos para processar outras solicitações reais.

O IAsyncDisposable substitui o IDisposable?

Direto ao ponto: NÃO ! A interface IAsyncDisposable não substitui a IDisposable. É uma forma adicional de descarte, principalmente para criar bibliotecas (que não controlam o código que usa o objeto a ser descartado). Se você implementar apenas IAsyncDisposable , seu aplicativo poderá ter vazamentos de recursos ou até mesmo uma exceção, dependendo do cenário .

Um ponto relevante para utilizá-lo como forma adicional é que existem algumas implementações que fazem uso de abstrações ou reflexão em busca da interface IDisposable, e como não a encontrarão, certamente teremos problemas durante a execução. Outro ponto relevante é a implementação dentro de métodos síncronos que exigem o bloqueio do contexto para sincronizá-lo, o que faz com que o uso assíncrono perca o sentido (veja a imagem abaixo).

Como implementar IAsyncDisposable junto com IDisposable

Há uma diferença no padrão de descarte assíncrono em comparação ao síncrono. Essa diferença ajuda a garantir a equivalência funcional com o padrão de descarte síncrono. Em outras palavras, o método DisposeAsyncCore() descartará recursos gerenciados de forma assíncrona, portanto, não é recomendado descartá-los de forma síncrona. Portanto, chame Dispose(false) em vez de Dispose(true) para garantir esse comportamento.

Dica: Se uma implementação for selada, o método DisposeAsyncCore() não será necessário, e a limpeza assíncrona poderá ser executada diretamente no método IAsyncDisposable.DisposeAsync().

Tenha cuidado com o empilhamento

Se uma exceção for lançada (exemplo abaixo) no construtor AnotherAsyncDisposable, nenhum objeto será descartado corretamente.

O exemplo de uma melhor construção de empilhamento é mostrado abaixo, garantindo o descarte correto para cada criação de objeto.

Algumas desvantagens da aplicação do Dispose assíncrono

  • Complexidade: Implementar e gerenciar operações assíncronas pode adicionar complexidade ao código. Isso inclui a necessidade de lidar com exceções e garantir que todos os recursos sejam liberados corretamente.
  • Sobrecarga de recursos: embora operações assíncronas possam melhorar a escalabilidade, elas também podem introduzir sobrecarga de recursos, como aumento de memória e uso de threads.
  • Dificuldade de Depuração: Depurar código assíncrono pode ser mais complicado do que depurar código síncrono. Exceções podem ser mais difíceis de rastrear e entender, especialmente quando ocorrem em contextos de execução diferentes.
  • Complexidade do teste: testar código assíncrono pode ser mais complexo, exigindo ferramentas e abordagens específicas para garantir que todas as condições e exceções sejam tratadas corretamente.

Conclusão

Muito se fala sobre o uso do Dispose assíncrono, e ele pode ser vantajoso principalmente para cenários onde o uso de recursos é caro, como em ambientes de nuvem, e desempenho, escalabilidade e poucos blocos são fatores muito desejados.  No entanto, tenha cuidado ao usá-los e adicione-os somente se realmente precisar equilibrar as desvantagens.


Tenham um excelente dia! Eu sou Fernando Cerqueira e entrego estratégias digitais para os desafios do presente, com propostas de inovação para um futuro sustentável.

Compatilhe

0 0 votos
Avaliação Global
0 Comentários
Categorias

Sobre o Autor

Picture of Fernando Cerqueira

Fernando Cerqueira

Eu sou Fernando Cerqueira e entrego estratégias digitais para os desafios do presente, com propostas de inovação para um futuro sustentável. Como arquiteto sênior, aproveito meus mais de 30 anos de experiência em arquitetura e desenvolvimento de software para projetar e implementar soluções baseadas em nuvem que ajudam os clientes a transformar seus negócios com tecnologia.

Outros Posts

Categorias

Guardrails Arquiteturais

Guardrails Arquiteturais definem os princípios de segurança, conformidade e eficiência garantem uma infraestrutura sólida e bem direcionada para o negócio. Um dos papeis da arquitetura corporativa é o manter os conceito de guardrails. Uma visão mais holística da infraestrutura e suas relações com o impacto financeiro , continuidade do negócio

A Síndrome do Pato Flutuante na Era da IA

Precisamos ser cada vez mais humanos para sermos mais estratégicos com o uso da IA. Delegar para IA : Um caminho Insufiente Muitas empresas estão delegando a adoção de IA para suas áreas de tecnologia. À primeira vista, isso pode parecer lógico, mas será que é suficiente? Os impactos da

Dívidas Técnicas: um risco corporativo que cresce silenciosamente

É necesssário  evolução do pensamento crítico sobre as dívidas técnicas para uma proposta sustentável de dívidas corporativas. Dívidas Técnicas: um risco corporativo além do código Dívidas técnicas NÃO SÃO apenas um problema de projeto de software, são um RISCO CORPORATIVO. Uma dívida técnica, devido a sua natureza, só tende a

Adotar classes seladas em .NET por padrão é uma ótima escolha

Adotar classes seladas em .NET por padrão é uma ótima escolha. Saiba por que! Em .net todas as classes que são criadas por padrão (template), permitem herança. Esta opção padrão deixa mais flexível qualquer implementação por herança, mas sendo sincero, acredito não ser esta a melhor opção : Uma classe

Documentação moderna centrada em estímulos contextuais

Introdução Essa frase provocativa abaixo “Documentos escritos que não são lidos, não vale os bytes que ocupam – Elemar Júnior” serve como ponto de partida para uma reflexão mais crítica frente aos desafios de uma documentação moderna, que exige novas abordagens e uma mudança cultural para agregar valor. O desafio

"Não existe decisões técnicas , decisões de tecnologia devem ter um proposito que resolva um problema de negócio."

Fernando Cerqueira | Arquiteto Corporativo

Sua Reflexão

0
Adoraria saber sua opinião, comente.x