Delphi Multithreading Moderno: Escreva Código Assíncrono Limpo e sem Complicação

Em 2025, durante minhas palestras na Embarcadero Conference, Luso Delphi e CodeRage, eu terminei minha apresentação com alguns slides “misteriosos” (Slides 17 e 18).
Eu falei sobre a jornada do desenvolvedor: saímos da complexidade manual da TThread, evoluímos para a eficiência da PPL (Parallel Programming Library), mas ainda faltava algo.
Quem usa PPL intensivamente conhece o problema. Para orquestrar pipelines complexos (baixar dados -> processar -> salvar -> atualizar UI), acabamos caindo na temida “Pyramid of Doom”: aninhamento excessivo de métodos anônimos, blocos try..except repetitivos e chamadas manuais de TThread.Queue para não congelar a tela.
Naquele slide, eu prometi uma visão de futuro: Uma interface fluente onde o código assíncrono pudesse ser lido como uma frase.
A espera acabou. A promessa foi cumprida.
Hoje, apresento oficialmente o Dext.Threading.Async — a implementação real daquele conceito, agora disponível no Dext Framework.
O Problema: A “Dívida” da Complexidade
Seção intitulada “O Problema: A “Dívida” da Complexidade”No meu livro, “Delphi Multithreading”, dedico capítulos inteiros ensinando como proteger suas threads, evitar Race Conditions e garantir que exceções não derrubem sua aplicação silenciosamente. Essa base teórica é inegociável.
Porém, no dia a dia, escrever toda essa infraestrutura “na unha” para cada botão do seu sistema é cansativo. Veja o padrão tradicional:
// O jeito padrão de usar a PPLTTask.Run(procedurebegin try var Dados := DownloadBytes; // Aninhamento... TThread.Synchronize(nil, procedure begin AtualizaUI(Dados); // E se o Form já fechou? Access Violation. end); except on E: Exception do HandleError(E); // Boilerplate repetitivo end;end);A Solução: Dext Fluent Async
Seção intitulada “A Solução: Dext Fluent Async”
Com o novo motor do Dext, abstraímos a complexidade da ITask, IFuture e o tratamento de exceções em uma sintaxe declarativa.
Vamos a um exemplo real? Imagine um Dashboard que precisa carregar 3 painéis pesados simultaneamente ao abrir a tela. Se fizéssemos sequencial, o usuário esperaria a soma dos tempos. Com o Dext, disparamos em paralelo e o código permanece limpo:
uses Dext.Threading.Async;
procedure TFormDashboard.LoadDashboard;begin // 1. Carrega o Perfil do Usuário (I/O Bound) // Dispara e esquece a complexidade. O Dext gerencia a thread. var Task1 := TAsyncTask.Run<TUserProfile>( function: TUserProfile begin // Executa em Background Thread Pool Result := UserService.GetProfile(Self.UserId); end) .ThenBy(procedure(User: TUserProfile) begin // Executa processamento adicional em background se necessário LogAcesso(User); end) .OnComplete(procedure(User: TUserProfile) begin // Executa AUTOMATICAMENTE na Main Thread (seguro para VCL/FMX) UserLabel.Caption := 'Bem vindo, ' + User.Name; imgAvatar.Bitmap := User.Avatar; end) .OnException(procedure(E: Exception) begin // Tratamento centralizado de erro na Main Thread ShowMessage('Erro ao carregar perfil: ' + E.Message); end) .Start; // Inicia a execução
// 2. Carrega Gráfico Financeiro (CPU Bound) // Executa em PARALELO ao anterior var Task2 := TAsyncTask.Run<TFinancialData>( function: TFinancialData begin // Verifica cancelamento automaticamente antes de começar Result := FinanceService.CalculateHeavyMetrics(CurrentYear); end) .OnComplete(procedure(Data: TFinancialData) begin ChartSales.Series[0].Add(Data.Values); end) .Start;
// 3. Atualiza Notificações var Task3 := TAsyncTask.Run<Integer>( function: Integer begin Result := NotificationService.CountUnread; end) .OnComplete(procedure(Count: Integer) begin Badge.Text := Count.ToString; Badge.Visible := Count > 0; end) .Start;
// Aguarda todas as tarefas finalizarem TAsyncTask.WaitForAll([Task1, Task2, Task3]);end;O que ganhamos aqui?
- Legibilidade: Lemos o código de cima para baixo, como uma história.
- Segurança de Thread: O
OnCompleteeOnExceptionjá garantem a sincronização com a Main Thread ou thread chamadora. Acabou oTThread.Queueespalhado pelo código. - Propagação de Exceção: Se o
GetProfilefalhar, o fluxo pula oThenBye cai direto noOnException. Semtry..exceptpoluindo a regra de negócio.
A Rede de Segurança: Cancellation Tokens
Seção intitulada “A Rede de Segurança: Cancellation Tokens”Mas e se o usuário fechar o formulário enquanto essas 3 tarefas estão rodando? Teremos um Access Violation ao tentar atualizar o UserLabel?
É aqui que entra a teoria que ensino no Capítulo 4 do livro: Cancelamento Cooperativo.
O Dext implementa o padrão ICancellationToken (inspirado no .NET) de forma transparente. Você pode passar um token para a tarefa, e a cadeia fluente verifica esse token antes de cada etapa.
// Vincula o Token ao ciclo de vida do FormFTokenSource := TCancellationTokenSource.Create;
TAsyncTask.Run(...) .WithCancellation(FTokenSource.Token) // A mágica acontece aqui .OnComplete(...) .Start;
procedure TFormDashboard.FormDestroy(Sender: TObject);begin // Ao destruir o form, cancela tudo que está pendente. // O Dext impede que o OnComplete (que acessa componentes visuais) seja executado. FTokenSource.Cancel;end;Isso resolve um dos bugs mais comuns e difíceis de rastrear em aplicações Delphi Multithread: o callback que tenta acessar um objeto destruído.
Teoria e Prática: O “Power Duo”
Seção intitulada “Teoria e Prática: O “Power Duo””O Dext Framework entrega a ferramenta pronta para produção. Mas para usar multithreading com maestria, você precisa entender o que realmente está acontecendo. Por que o Pool de Threads é melhor que criar Threads manuais? O que é Context Switching? Como funcionam as Primitivas de Sincronização?

É por isso que digo que o Livro e o Framework formam um par perfeito:
-
📘 O Livro (Delphi Multithreading): Ensina a base, a arquitetura e os “porquês”. O código fonte dos exemplos do livro (incluindo a implementação pura do CancellationToken) está disponível abertamente para estudo.
-
Repositório (PT): github.com/cesarliws/DelphiMultithreadingBookCode
-
Repositório (EN): github.com/cesarliws/DelphiMultithreadingBookCodeEnglishEdition
-
🚀 O Framework (Dext): Entrega a implementação produtiva, testada e pronta para o dia a dia, aplicando os conceitos do livro em uma API moderna.
Conclusão
Seção intitulada “Conclusão”Cumpri minha promessa feita no CodeRage. O Fluent Tasks não é mais apenas um slide de PowerPoint; é código real que você pode usar hoje para eliminar a complexidade do seu projeto.

Convido você a baixar o Dext, testar o Dext.Threading.Async e, se quiser dominar a engenharia por trás disso, garantir sua cópia do livro no meu site.
Documentação Async API: https://github.com/cesarliws/dext/blob/main/Docs/async-api.md
Baixe o Dext: https://github.com/cesarliws/dext
Garanta o Livro: https://www.cesarromero.com.br/
Vamos codar (em paralelo)! 🚀
#Delphi #Multithreading #DelphiMultithreadingBook #DextFramework #AsyncProgramming #CodeRage #SoftwareArchitecture #OpenSource