Use Foreach com Paralelismo Assincrono
Use Foreach com Paralelismo Assincrono

Salve Dev, me chamo Jorel Magatti e sou Desenvolvedor c# .Net, aqui trago uma implementações simples na utilização de um foreach com paralelismo assíncrono, em uma demanda recente, acabei precisando deste cara para melhorar a performance de um processo, para processar uma lista mais rápido e ter certeza que cada processamento (Task) foi executado por completo , achei muito interessante por isso trago aqui um modelo de exemplo, para quem precisar.
Para a implementação de foreach com paralelismo assíncrono, é necessário instalar em seu projeto dois pacotes, o Nancy (no meu caso na versão 2.0.0) e AsyncEnumerator (no meu caso na versão 4.0.2), segue link dos pacotes :
Segue abaixo link oficial dos pacotes:
Estou utilizando .Net na versão 5 neste exemplo. Segue abaixo a implementação do foreach com paralelismo assíncrono em uma aplicação de console:
using Dasync;
using Dasync.Collections;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ForeachParalelismoAssincrono
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Implementação Foreach com paralelismo assíncrono!");
List<int> valoresParaProcessar = new List<int>() { 1,2,3,4,5 };
await valoresParaProcessar.ParallelForEachAsync(async item => {
await ExecutaProcesso(item);
}, 2);
Console.ReadKey();
}
public static async Task ExecutaProcesso(int valor)
{
Console.WriteLine($"execução {valor} => {DateTime.Now};");
await Task.Delay(TimeSpan.FromSeconds(1));
}
}
}Note que precisamos referenciar a ddl Dasync.Collections, por debaixo dos panos ele utiliza da dll AsyncEnumerator em seu funcionamento:

Note que a implementação de paralelismo utiliza o método de extensão .ParallelForeachAssync para listas de objeto:

Note que ele recebe como argumento um arrow functions async apontando o objeto de unidade referenciando o item da lista e também como argumento ele possui um valor inteiro correspondente ao parâmetro maxDegreeOfParallelism, em nosso exemplo recebendo o valor 2, esse parâmetro corresponde ao numero de task lançadas, isso significa que ele quando executar o paralelismo ele vai consumir a fila de 2 em 2 e aguardando a fim da execução do que estiver escrito no corpo do método do primeiro parâmetro. Um terceiro argumento do método ParallelForeachAssync que vale a pena mencionar é o CancellationToken cancellationToken, muito utilizado em work services, caso um evento de stop do seu serviço precise parar a aplicação, o paralelismo assíncrono usado ParallelForeachAssync através deste parâmetro, ele respeita o evento.
Após a execução deste modelo, olha como é processado cada item:

Note que a execução do paralelismo respeitou o parâmetro maxDegreeOfParallelism implementado com o valor 2 no modelo acima, onde ele executa este numero especificado de tasks em paralelo.

Atenção: A utilização da dll AsyncEnumerator costuma gera conflito com algumas expressões lambda , principalmente os usados no Entity Framework, neste caso eu costumo isolar o processo de consumo do foreach com paralelismo assíncrono, fazendo com que o processamento das Task paralelas, executem a chamada de um método ou função em outro arquivo, que possuem expressões lambda conflitantes.
Espero que goste da leitura e espero que este pequeno artigo tenha lhe ajudado em sua necessidade de entrega. Abraços Dev🚀🚀🚀
Comentários
Postar um comentário