Neste artigo, veremos como executar tarefas em paralelo e aprenderemos a usar a classe SemaphoreSlim para ajudar a controlar a execução de nossas tarefas.
É muito comum hoje em dia criarmos métodos assíncronos que recebem varias requisições ao mesmo tempo, mas imagine uma situação onde você teria que garantir que somente uma task executasse dentro do seu método por vez?
E que outra task só entraria depois que a primeira terminasse o processamento?
Ou ainda permitir que lotes de tasks entrassem em seu método por vez?
Pois bem em cenários onde ser torna necessário ter controle sobre a execução de suas tasks podemos usar a classe SemaphoreSlim do .NET, basicamente essa classe limita o número de threads que podem acessar um recurso compartilhado simultaneamente.
Para demonstrar vamos criar um código bem simples que simula a chamada a uma API.
Abaixo o código da chamada principal, vamos executar o mesmo código sem o objeto Semaphore e com o objeto Semaphore para compararmos depois a diferença:


No método InitProcess simplesmente estamos criando uma lista de tasks e dentro de um for adicionando 20 tarefas para serem executadas. Usamos o Task.WaitAll na linha 10 para executar as tarefas que neste caso serão executadas simultaneamente.
Depois de executar podemos observar pelo log gerado que o processamento demorou 1 segundo e 557 milissegundos:

Agora vamos executar o mesmo código utilizando o objeto Semaphore:

No método InitProcess inserimos uma variável do tipo SemaphoreSlim definindo ali o número 1 especificando que somente 1 request/entrada poderá ser executada simultaneamente na linha 3 do código.
Este objeto tem uma sobrecarga que permite a inclusão da quantidade de requests que pode ser feitas simultaneamente (InitialCount) e também o número máximo de requests que podem ser executadas simultaneamente(MaxCount).
Dentro do método ProcessWithSemaphore usamos dois métodos do objeto Semaphore: WaitAsync() e Release(), eles são responsáveis por fazer a execução, aguardar e liberar a posição para o semáforo.
Rodando o projeto novamente vamos ver como saída:

O processo demorou mais de 26 segundos para ser executado porque definimos pelo Semaphore que somente 1 solicitação poderia ser executada por vez. O processo foi mais lento que o primeiro exemplo mas foi executado de maneira “controlada“.
Este código inteiro pode ser visto aqui no meu github.
Referencias

É isso ae, aprendendo sempre! se curtiu ou ajudou comenta para fortalecer! obrigado e até a próxima.