Fala ai Radizeiros e Radizeiras, tudo bem com vocês?

Você tem alguma coisa chata dentro da sua aplicação que está demorando muito tempo?

No post de hoje irei lhe apresentar o parallel for, onde você pode utilizar e deixar ele processar tudo isso para você.

O parallel for é um recurso da biblioteca de paralelismo, para que façamos interações, ou seja, os laços de repetição, só que usando Tasks.

Isso mesmo, usando tarefas, não necessariamente cada laço vai em uma thread diferente, na verdade, cada laço será uma tarefa que realizará de forma assíncrona, ou seja, ela não irá ficar em cadeia.

Todos os loops vão ser realizados ao mesmo tempo, ou em tempo diferente, e não irão respeitar uma cadeia, ou seja, não irão entrar em uma fila.

Vamos construir um exemplo utilizando o parallel for, onde você irá compreender e poder aplicar para solucionar esses problemas que tem passado em suas aplicações.

Vamos deixar de muito papo, porque com toda a certeza você já está querendo saber como implementar o parallel for, não é verdade?

Vamos lá então?

Vamos criar um projetinho de exemplo.

Primeira coisa que você tem que fazer é importar nas uses do seu projeto a biblioteca de paralelismo, System.Threading.

Sem essa declaração nós não iremos conseguir seguir com a utilização do parallel for.

Dentro do primeiro botão iremos fazer o seguinte, primeiro vamos limpar o Memo que encontra-se no formulário, e fazer um for normal, aquele que já estamos acostumados.

procedure TForm1.Button1Click(Sender: TObject);
var
    i:integer;
begin
    Memo1.Lines.Clear;
    for i := 0 to 9 do
    begin
        sleep(100);
        Memo1.Lines.Add(i.tostring);
    end;
end;

Até então não temos nada de mais nesse exemplo não é verdade?

Observe que o exemplo demorou cerca de 1 segundo para cada interação, isso foi feito para que pudesse ver tudo adicionando dentro do Memo.

Agora vamos usar a biblioteca de paralelismo para realizar o que acabamos de fazer.

Dentro do nosso terceiro botão iremos declarar algumas coisas.

procedure TForm1.Button2Click(Sender: TObject);
begin
    Memo1.Lines.Clear;
    TParallel.For(0,9,
    procedure (Index: Integer)
    begin
        sleep(100);
        TThread.Queue(TThread.CurrentThread,
        procedure
        begin
            memo1.lines.add(Index.ToString);
        end);
    end);
end;

Observe que primeiro limpamos o Memo, e logo em seguida usamos nossa biblioteca, que foi o TParallel.

Você pode observar que esse TParallel tem vários recursos que podemos utilizar.

Mas hoje iremos utilizar o for, como você pode observar no código acima, onde fazemos uma interação, substituímos o for normal, pelo o for do parallel.

O for do parallel é semelhante ao que já estamos acostumados, onde o primeiro valor é o inicial, o segundo é até onde iremos chegar, e logo depois a interação, que nesse caso usamos um método anônimo com um parâmetro.

Como fazemos no for tradicional, onde usamos o I, no método anônimo do parallel for, ele precisa desse parâmetro de interação.

Observe que fizemos a mesma coisa que fizemos no primeiro botão, sendo que agora usando a biblioteca de paralelismo, para que esse camarada seja executado em várias tarefas diferente.

Deu para perceber uma particularidade quando usamos o parallel for?

Observe que o primeiro botão ele executa de forma ordenada, e logo em seguida o botão com o parallel for, ele executou a numeração de forma desordenada.

As interações não obedece uma ordem, pois elas estão ocorrendo simultaneamente.

Quando se usa o parallel for você não consegue controlar a sequência dessas interações.

Todas as interações são executadas, porém em tarefas assíncronas, ou seja, elas estão rodando todas ao mesmo tempo, uma não depende da outra.

Nesse caso o parallel for distribui em diversas tarefas que consequentemente podem ser distribuídas em threads diferente.

Se você quer seguir uma sequência não usa o parallel for!

Para casos que não precisem de uma interação ou seguir uma sequência, vá de parallel for que terá um maior rendimento.

Quando você executa o parallel for, ele roda em tarefas separadas, porém enquanto ele estiver executando a aplicação acaba travando, observe que somente depois dos 10 segundos que conseguimos mexer no exemplo.

O parallel for no contexto geral, onde ele está inserindo, ainda está rodando na thread principal, ele só está dividindo as tarefas de interação.

Então o legal para que você não tenha essa trava no seu sistema, é rodar o parallel for já dentro de uma thread separada.

O que fazemos é.

procedure TForm1.Button2Click(Sender: TObject);
begin
    Memo1.Lines.Clear;
    TTask.Run(
    procedure
    begin
        TParallel.For(0,9,
        procedure (Index: Integer)
        begin
            sleep(100);
            TThread.Queue(TThread.CurrentThread,
            procedure
            begin
               memo1.lines.add(Index.ToString);
            end);
        end);
    end);
end;

Observe que colocamos esse nosso parallel for dentro de uma tarefa separada da principal.

Agora nossa aplicação não trava mais.

Viu como podemos utilizar tranquilamente as ferramentas de paralelismo e melhorar o desempenho das aplicações.

Esse e outros conteúdos você pode encontrar dentro do CLUBE DOS PROGRAMADORES EM DELPHI, o maior acervo de Delphi em um único lugar.

E caso você tenha interesse de conhecer mais sobre PPL acessa o nosso portal do CLUBE DE PROGRAMADORES EM DELPHI, onde você não só terá conteúdos relacionados aos generics, mas uma quantidade enorme de conteúdos que poderá lhe ajudar muito no seu dia a dia, é uma verdadeira NETFLIX para os programadores Delphi.

CLIQUE AQUI E SAIBA MAIS SOBRE O CLUBE DOS PROGRAMADORES DELPHI