Episódio 26 — Agendamento assíncrono por tempo e intervalo
Um dos desafios comuns no desenvolvimento de aplicações é realizar tarefas que precisam acontecer em tempos distintos — seja com base em um agendamento específico (como um horário) ou em intervalos recorrentes (como a cada 10 minutos). Fazer isso sem bloquear a interface do usuário exige atenção.
Com TSafeThread e TTaskChain, podemos implementar mecanismos robustos de agendamento sem depender de TTimernem recorrer a estruturas acopladas ao formulário principal. Neste episódio, vamos mostrar como.
🧠 O problema
TTimeré simples, mas roda na thread principal. Ou seja: se a UI estiver ocupada, a execução do timer pode ser atrasada.- Reusar
Sleepem threads bloqueia tudo ou exige malabarismos comTThread.CreateAnonymousThreadeSynchronize. - E se quisermos que uma tarefa só aconteça após 5 segundos? Ou a cada 10 minutos, mas de forma paralela?
A resposta está no uso controlado de TThread.Sleep, mas dentro de TSafeThread, com callbacks bem definidos e o ciclo de vida da thread sob controle.
✅ Solução 1: atraso programado
Para executar uma tarefa com atraso, basta adicionar um Sleep no corpo do SetOnExecute:
TSafeThread.ExecuteThread(
TSafeThreadParams.New
.SetOnExecute(
procedure(Context: TThreadContext)
begin
Sleep(5000); // aguarda 5 segundos
// Executa sua tarefa aqui
end)
);
✅ Solução 2: execução recorrente
Vamos imaginar uma tarefa que precise ser executada a cada 10 segundos. Podemos usar um loop com Sleep dentro do OnExecute, controlado por um CancelRequested:
TSafeThread.ExecuteThread(
TSafeThreadParams.New
.SetOnExecute(
procedure(Context: TThreadContext)
begin
while not Context.ThreadCancel do
begin
// tarefa
TThread.Synchronize(nil, procedure begin
// atualizar a UI
end);
Sleep(10000); // 10 segundos
end;
end)
);
Isso é ideal para sincronização com servidores, polling ou notificações.
🧩 Integrando com TTaskChain
Também é possível encadear tarefas que iniciam após um atraso:
TaskChain.AddTask('Aguardar 3s',
procedure(const TaskName: string; OnSuccess: TProc; OnError: TErrorCallback)
begin
Sleep(3000);
OnSuccess();
end);
Ou agendar um ciclo recorrente, quebrando em múltiplos passos (com contador, por exemplo).
📌 Considerações
- Evite
Sleepmuito longo (>30s) em ambientes móveis — use ciclos curtos. - Sempre valide
CancelRequestedpara permitir cancelamento com segurança. - Prefira
TThread.QueueouSynchronizeao interagir com UI.
✨ Conclusão
Com TSafeThread, controlar o tempo entre execuções é simples, seguro e desacoplado. Seja para tarefas pontuais ou recorrentes, o modelo proposto neste episódio substitui com vantagens o uso do TTimer, oferecendo controle total da execução.
No próximo episódio, veremos como:
- Controlar múltiplos agendamentos com granularidade
- Criar estruturas de agendamento por data/hora com persistência
- Integrar com bancos locais (SQLite) ou serviços online para controle de execução agendada
O tempo certo para executar uma tarefa nem sempre é agora. Mas com controle, toda execução tem seu momento.