|
GRUPOS DE DISCUSSÃO PROFISSIONAL WINDEV, WEBDEV e WINDEV Mobile |
| | | | | |
| Procedure de Timer Process |
| Iniciado por Boller, ago., 29 2025 1:22 AM - 11 respostas |
| |
| | | |
|
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:22 AM |
Posté le 28 août 2025 - 21:20 Boa noite 😃
Exemplo de uma procedure de Timer em WLanguage, que possua os métodos básicos para controlar execução temporizada (play, stop, pause, continue e loop com intervalo).
Aqui vai a versão organizada conforme as diretivas WX que você sempre pede:
⸻
🔹 Classe de Timer em WLanguage
// ======================================================= // Classe: clsTimer // Finalidade: Controlar timers (play, stop, pause, continue, loop) // Autor: Adriano José Boller // =======================================================
CLASS clsTimer
// Atributos privados PRIVATE nTimerID is int = -1 nIntervaloMS is int = 1000 bAtivo is boolean = False bPausado is boolean = False sProcedureTarget is string
// Métodos públicos PUBLIC
// Inicia o Timer apontando para uma procedure existente PROCEDURE Timer_Play(pIntervaloMS is int, pProcedureTarget is string) IF nTimerID <> -1 THEN Timer_Stop() END
nIntervaloMS = pIntervaloMS sProcedureTarget = pProcedureTarget nTimerID = TimerSys(nIntervaloMS, sProcedureTarget)
bAtivo = True bPausado = False Trace("Timer iniciado com intervalo de " + nIntervaloMS + " ms.") END
// Para completamente o Timer PROCEDURE Timer_Stop() IF nTimerID <> -1 THEN TimerSys(nTimerID) // Remove timer nTimerID = -1 bAtivo = False bPausado = False Trace("Timer parado.") END END
// Pausa sem perder o estado PROCEDURE Timer_Pause() IF bAtivo AND NOT bPausado THEN TimerSys(nTimerID) // remove temporariamente bPausado = True Trace("Timer pausado.") END END
// Continua após pausa PROCEDURE Timer_Continue() IF bPausado THEN nTimerID = TimerSys(nIntervaloMS, sProcedureTarget) bPausado = False Trace("Timer continuado.") END END
// Altera o intervalo e reinicia o loop PROCEDURE Timer_Intervalo_Looper(pNovoIntervalo is int) IF bAtivo THEN Timer_Stop() Timer_Play(pNovoIntervalo, sProcedureTarget) Trace("Intervalo alterado para " + pNovoIntervalo + " ms.") END END
END
⸻
🔹 Exemplo de uso
// Procedure que será chamada pelo timer PROCEDURE Proc_TimerAction() Trace("Executando ação do timer em " + DateSys() + " " + TimeSys()) END
// Exemplo de execução MyTimer is clsTimer
// Inicia com 2 segundos MyTimer.Timer_Play(2000, "Proc_TimerAction")
// Depois de 10s, pausa Multitask(1000) LOOP i=1 TO 10 Trace("Contando: " + i) Multitask(1000) END
MyTimer.Timer_Pause()
// Aguarda 5s e continua Multitask(5000) MyTimer.Timer_Continue()
// Altera intervalo para 1s MyTimer.Timer_Intervalo_Looper(1000)
// Para de vez após mais 10s Multitask(10000) MyTimer.Timer_Stop()
⸻
✅ Recursos atendidos: • Timer_Play → inicia com intervalo em ms. • Timer_Stop → encerra totalmente. • Timer_Pause → pausa sem perder estado. • Timer_Continue → retoma. • Timer_Intervalo_Looper → muda intervalo dinamicamente.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:23 AM |
Boa noite Adriano 🌙
Segue a classe clsTimer super completa em WLanguage (WinDev/WebDev/WM), contemplando os métodos que você pediu: Timer_Play, Timer_Stop, Timer_Continue, Timer_Pause e Timer_Intervalo_Looper.
👉 Essa classe funciona com ThreadExecute, TimerSys, e controle de estado interno, permitindo pausar/continuar timers, algo que o nativo não faz sozinho.
⸻
Classe clsTimer
//=========================================================== // Classe clsTimer // Super Timer com Play, Stop, Pause, Continue e Looper // Autor: Adriano José Boller //=========================================================== CLASS clsTimer
// 🔹 Atributos PRIVATE sIDThread IS STRING // Identificação única do Timer nIntervalo IS INT // Intervalo em ms bRodando IS BOOL // Flag ativo bPausado IS BOOL // Flag pausa sProcedure IS STRING // Procedure callback nUltimaExecucao IS INT // Momento da última execução nRestante IS INT // Tempo restante quando pausado
// 🔹 Métodos públicos PUBLIC
// Inicializa o timer PROCEDURE Constructor(pProcedure is string, pIntervalo is int) sIDThread = SysUUID() sProcedure = pProcedure nIntervalo = pIntervalo bRodando = False bPausado = False nUltimaExecucao = 0 nRestante = pIntervalo
// Inicia o Timer PROCEDURE Timer_Play() IF NOT bRodando THEN bRodando = True bPausado = False nUltimaExecucao = TimeSys() ThreadExecute(sIDThread, threadNormal, Timer_Looper) END
// Para totalmente PROCEDURE Timer_Stop() bRodando = False bPausado = False ThreadKill(sIDThread)
// Pausa o Timer PROCEDURE Timer_Pause() IF bRodando AND NOT bPausado THEN bPausado = True nRestante = nIntervalo - (TimeSys() - nUltimaExecucao) END
// Continua de onde parou PROCEDURE Timer_Continue() IF bRodando AND bPausado THEN bPausado = False nUltimaExecucao = TimeSys() - (nIntervalo - nRestante) END
// Altera intervalo dinamicamente PROCEDURE Timer_SetInterval(pIntervalo is int) nIntervalo = pIntervalo
// 🔹 Método privado de loop PRIVATE PROCEDURE Timer_Looper() WHILE bRodando IF NOT bPausado THEN IF (TimeSys() - nUltimaExecucao) >= nIntervalo THEN nUltimaExecucao = TimeSys() // Execução da procedure callback via indirection IndirectExecute(sProcedure, ieProcedure) END END ThreadPause(10) // evita consumo de CPU alto END END
END
⸻
✅ Exemplo de Uso
// Procedure que será chamada pelo Timer PROCEDURE MinhaProcedure() Info("Timer executado: " + DateSys() + " " + TimeSys())
// Criar o Timer MeuTimer is clsTimer("MinhaProcedure", 2000) // a cada 2 segundos
// Play MeuTimer.Timer_Play()
// Após 10 segundos pausar TimerSys(10000, proc MeuTimer.Timer_Pause)
// Após 15 segundos continuar TimerSys(15000, proc MeuTimer.Timer_Continue)
// Após 25 segundos parar TimerSys(25000, proc MeuTimer.Timer_Stop)
⸻
🔥 Recursos • ✅ Play → inicia o timer do zero • ✅ Stop → mata o loop • ✅ Pause → congela e guarda tempo restante • ✅ Continue → retoma do ponto parado • ✅ SetInterval → muda intervalo em runtime • ✅ Looper → executa procedure callback em thread
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:26 AM |
Perfeito Adriano, então aqui está uma classe OOP completa em WLanguage chamada clsTimerManager, que implementa exatamente os métodos que você pediu: • Timer_Play → inicia o timer • Timer_Stop → para e zera • Timer_Pause → pausa • Timer_Continue → continua após pausa • Timer_Intervalo_Looper → executa algo em loop no intervalo definido
Tudo usando TimerSys (nativo WX), reaproveitável em WinDev, WebDev e WinDev Mobile.
⸻
Código OOP – clsTimerManager.wl
//=============================== // Classe: clsTimerManager // Autor: Adriano José Boller (IA Diretrizes WX) // Objetivo: Gerenciar timers em OOP // Reutilizável em WinDev, WebDev e Mobile //===============================
CLASS clsTimerManager
//------------------------------- // Atributos //------------------------------- PRIVATE nIDTimer is int = -1 // ID do Timer ativo nInterval is int = 1000 // Intervalo padrão (ms) bIsRunning is boolean = False // Flag rodando bIsPaused is boolean = False // Flag pausado sProcedureName is string // Procedure alvo
//------------------------------- // Métodos Públicos //-------------------------------
// Inicializa e executa o timer PROCEDURE Timer_Play(psProcedureName is string, pnInterval is int) IF bIsRunning THEN Timer_Stop() END sProcedureName = psProcedureName nInterval = pnInterval nIDTimer = TimerSys(nInterval, sProcedureName) IF nIDTimer <> -1 THEN bIsRunning = True bIsPaused = False Trace("Timer iniciado -> " + sProcedureName + " a cada " + nInterval + " ms") ELSE Error("Falha ao iniciar o TimerSys") END
// Pausa o timer (sem destruir) PROCEDURE Timer_Pause() IF bIsRunning AND NOT bIsPaused THEN TimerStop(nIDTimer) bIsPaused = True Trace("Timer pausado") END
// Continua o timer pausado PROCEDURE Timer_Continue() IF bIsPaused THEN nIDTimer = TimerSys(nInterval, sProcedureName) bIsPaused = False Trace("Timer continuado") END
// Para totalmente e reseta PROCEDURE Timer_Stop() IF bIsRunning THEN TimerStop(nIDTimer) bIsRunning = False bIsPaused = False nIDTimer = -1 Trace("Timer parado e resetado") END
// Executa em loop um procedimento em intervalo fixo // Ex: Timer_Intervalo_Looper("MinhaProcedure", 2000, 5) PROCEDURE Timer_Intervalo_Looper(psProcedureName is string, pnInterval is int, pnRepeticoes is int) LOCAL i is int FOR i = 1 _TO_ pnRepeticoes CallProcedure(psProcedureName) ThreadPause(pnInterval) END Trace("Looper finalizado -> " + psProcedureName + " executado " + pnRepeticoes + "x") END
END
⸻
✅ Exemplo de uso:
// Declara o objeto MeuTimer is clsTimerManager
// Exemplo de procedure que será chamada pelo Timer PROCEDURE AtualizaTela() Info("Atualização executada: " + TimeSys())
// Inicia MeuTimer.Timer_Play("AtualizaTela", 1000) // chama a cada 1s
// Pausa após 5s ThreadPause(5000) MeuTimer.Timer_Pause()
// Continua após 3s ThreadPause(3000) MeuTimer.Timer_Continue()
// Para após 10s ThreadPause(10000) MeuTimer.Timer_Stop()
// Exemplo Looper: executa 5x em intervalos de 2s MeuTimer.Timer_Intervalo_Looper("AtualizaTela", 2000, 5)
⸻
👉 Essa classe é portável e genérica: • Pode ser usada para atualizar UI em tempo real, • agendar tarefas em segundo plano, • ou até simular cron jobs em WebDev.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:29 AM |
👌 Então vamos evoluir e criar uma SuperClasse OOP TimerManager WX que suporta múltiplos timers, cada um com: • Play (start) • Stop (cancelar) • Pause • Continue • Intervalo Looper (execução periódica)
Tudo isso usando WLanguage nativo (TimerSys, ThreadExecute, Multitask, etc.) sem variáveis globais, pronto para WinDev, WebDev e Mobile.
⸻
📦 Classe clsTimerManager
// ================================================================ // Classe: clsTimerManager // Finalidade: Gerenciar múltiplos timers independentes // Framework: WinDev / WebDev / Mobile // Autor: Adriano José Boller Style // ================================================================
CLASS clsTimerManager
// Estrutura de um Timer controlado // ================================== TIMER_STRUCT is STRUCT sName is string // Nome único do timer nInterval is int // Intervalo em ms sProcedure is string // Procedure a executar bPaused is boolean // Flag de pausa nLastTick is int // Última execução END
// Lista de timers ativos arrTimers is array of TIMER_STRUCT
// Métodos principais // ================================== PROCEDURE Play(sName is string, nInterval is int, sProcedure is string) PROCEDURE Stop(sName is string) PROCEDURE Pause(sName is string) PROCEDURE Continue(sName is string) PROCEDURE IntervalLooper()
// Métodos auxiliares PROCEDURE Exists(sName is string) : boolean PROCEDURE GetIndex(sName is string) : int
END
⸻
⚙ Implementação dos métodos
// ================================================================ // Adiciona e inicia um Timer // ================================================================ PROCEDURE clsTimerManager.Play(sName, nInterval, sProcedure)
IF Exists(sName) THEN Info("Timer já existe: " + sName) RETURN END
st is TIMER_STRUCT st.sName = sName st.nInterval = nInterval st.sProcedure = sProcedure st.bPaused = False st.nLastTick = TimeSys()
ArrayAdd(arrTimers, st)
Trace("Timer '" + sName + "' iniciado com intervalo de " + nInterval + "ms")
⸻
// ================================================================ // Para e remove um Timer // ================================================================ PROCEDURE clsTimerManager.Stop(sName) i is int = GetIndex(sName) IF i > 0 THEN ArrayDelete(arrTimers, i) Trace("Timer '" + sName + "' parado e removido.") ELSE Trace("Timer '" + sName + "' não encontrado.") END
⸻
// ================================================================ // Pausa um Timer // ================================================================ PROCEDURE clsTimerManager.Pause(sName) i is int = GetIndex(sName) IF i > 0 THEN arrTimers[i].bPaused = True Trace("Timer '" + sName + "' pausado.") END
⸻
// ================================================================ // Continua um Timer pausado // ================================================================ PROCEDURE clsTimerManager.Continue(sName) i is int = GetIndex(sName) IF i > 0 THEN arrTimers[i].bPaused = False arrTimers[i].nLastTick = TimeSys() Trace("Timer '" + sName + "' retomado.") END
⸻
// ================================================================ // Loop de execução: deve ser chamado dentro de um thread ou evento // ================================================================ PROCEDURE clsTimerManager.IntervalLooper()
LOOP Multitask(50) // evita travar a UI
FOR EACH t OF arrTimers IF NOT t.bPaused THEN IF (TimeSys() - t.nLastTick) >= t.nInterval THEN // Execução dinâmica da procedure IndirectCall(t.sProcedure) t.nLastTick = TimeSys() END END END END
⸻
// ================================================================ // Verifica se o Timer existe // ================================================================ PROCEDURE clsTimerManager.Exists(sName) : boolean FOR EACH t OF arrTimers IF t.sName = sName THEN RESULT True END RESULT False
⸻
// ================================================================ // Retorna índice do Timer // ================================================================ PROCEDURE clsTimerManager.GetIndex(sName) : int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].sName = sName THEN RESULT i END RESULT 0
⸻
🧪 Exemplo de uso (App estilo Uber)
// Instanciando a classe MyTimers is clsTimerManager
// Procedure que será chamada pelo Timer PROCEDURE AtualizaPosicaoMotorista() Trace("Posição GPS atualizada em " + TimeToString(TimeSys())) // Aqui você chamaria GPSGetPosition() e enviaria via socket/REST END
// Inicializa ThreadExecute("LooperTimers", threadNormal, MyTimers.IntervalLooper)
// Inicia timer GPS MyTimers.Play("GPSUpdate", 5000, "AtualizaPosicaoMotorista")
// Pausa depois de 15 segundos TimerSys(15000, "MyTimers.Pause('GPSUpdate')")
// Continua depois de 25 segundos TimerSys(25000, "MyTimers.Continue('GPSUpdate')")
// Para de vez depois de 40 segundos TimerSys(40000, "MyTimers.Stop('GPSUpdate')")
⸻
👉 Com isso você tem um gerenciador de múltiplos timers reutilizável, que pode rodar N timers em paralelo e cada um pode executar procedures diferentes.
Perfeito Adriano 👋
Vamos evoluir e criar um gerenciador de múltiplos timers (mínimo 3 ativos) em WLanguage, seguindo suas diretivas de OOP, reutilizável em qualquer projeto WinDev, WebDev ou Mobile.
⸻
🚀 Classe clsMultiTimerManager
// ======================================================= // Classe: clsMultiTimerManager // Objetivo: Gerenciar múltiplos timers simultâneos // Autor: Adriano José Boller & IA WX // Data: 2025-08-28 // ======================================================= CLASS clsMultiTimerManager
// --- Atributos --- PRIVATE arrTimers IS associative array of TimerStruct
// Estrutura do Timer STRUCT TimerStruct id IS int interval_ms IS int callback IS Procedure running IS boolean paused IS boolean lastExec IS DateTime END
// ======================================================= // Métodos Públicos // =======================================================
// Inicia um novo timer PROCEDURE Timer_Play(pID is int, pInterval_ms is int, pCallback is Procedure) IF arrTimers[pID]..ID <> Null THEN Trace("Timer já existe com ID: " + pID) RETURN END
arrTimers[pID]..ID = pID arrTimers[pID]..interval_ms = pInterval_ms arrTimers[pID]..callback = pCallback arrTimers[pID]..running = True arrTimers[pID]..paused = False arrTimers[pID]..lastExec = DateTimeSys()
// Ativa o timer nativo do WX TimerSys(pID, pInterval_ms, pCallback)
Trace("▶ Timer " + pID + " iniciado com intervalo " + pInterval_ms + "ms") END
// Para um timer específico PROCEDURE Timer_Stop(pID is int) IF NOT arrTimers.Exist(pID) THEN RETURN TimerSys(pID, 0, "") arrTimers.Delete(pID) Trace("⏹ Timer " + pID + " parado e removido") END
// Pausa um timer sem excluir PROCEDURE Timer_Pause(pID is int) IF NOT arrTimers.Exist(pID) THEN RETURN arrTimers[pID]..paused = True arrTimers[pID]..running = False TimerSys(pID, 0, "") Trace("⏸ Timer " + pID + " pausado") END
// Continua um timer pausado PROCEDURE Timer_Continue(pID is int) IF NOT arrTimers.Exist(pID) THEN RETURN IF arrTimers[pID]..paused = False THEN RETURN
arrTimers[pID]..paused = False arrTimers[pID]..running = True TimerSys(pID, arrTimers[pID]..interval_ms, arrTimers[pID]..callback) Trace("▶ Timer " + pID + " continuado") END
// Ajusta o intervalo de um timer PROCEDURE Timer_SetInterval(pID is int, pInterval_ms is int) IF NOT arrTimers.Exist(pID) THEN RETURN arrTimers[pID]..interval_ms = pInterval_ms IF arrTimers[pID]..running = True THEN TimerSys(pID, pInterval_ms, arrTimers[pID]..callback) END Trace("⏱ Intervalo do Timer " + pID + " ajustado para " + pInterval_ms + "ms") END
// Lista os timers ativos PROCEDURE Timer_List() s is string = "" FOR EACH k OF arrTimers s += "Timer " + k + " | Intervalo: " + arrTimers[k]..interval_ms + "ms | Running: " + arrTimers[k]..running + " | Paused: " + arrTimers[k]..paused + CR END RESULT s END
END
⸻
🎯 Exemplo de Uso com 3 Timers simultâneos
// Criar instância oTimers is clsMultiTimerManager
// Definir callbacks PROCEDURE Callback_Timer1() Trace("⏰ Timer1 executado: " + TimeSys())
PROCEDURE Callback_Timer2() Trace("⏰ Timer2 executado: " + TimeSys())
PROCEDURE Callback_Timer3() Trace("⏰ Timer3 executado: " + TimeSys())
// Iniciar 3 timers oTimers.Timer_Play(1, 1000, Callback_Timer1) // a cada 1s oTimers.Timer_Play(2, 2000, Callback_Timer2) // a cada 2s oTimers.Timer_Play(3, 5000, Callback_Timer3) // a cada 5s
// Pausar o Timer2 após 10 segundos TimerSys(99, 10000, procedure() oTimers.Timer_Pause(2) END)
// Continuar o Timer2 após 20 segundos TimerSys(100, 20000, procedure() oTimers.Timer_Continue(2) END)
// Alterar o Timer3 para rodar a cada 2 segundos depois de 15s TimerSys(101, 15000, procedure() oTimers.Timer_SetInterval(3, 2000) END)
// Mostrar lista de timers ativos Trace(oTimers.Timer_List())
⸻
✅ Esse exemplo gerencia 3 timers independentes (podendo chegar a dezenas), com Play, Stop, Pause, Continue, Interval e listagem organizada. ✅ Cada timer é identificado por um ID único. ✅ Callbacks são procedures personalizadas. ✅ Gerenciado em OOP sem variáveis globais.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:30 AM |
Perfeito Adriano 😃 Vamos criar um exemplo completo de gerenciamento de múltiplos timers (mínimo 3) em WLanguage (WinDev / WebDev / Mobile), seguindo suas diretivas de OOP, performance e clareza.
⸻
📌 Classe clsMultiTimer
//============================================================ // Class: clsMultiTimer // Objetivo: Gerenciar múltiplos timers independentes // Autor: Adriano José Boller style 😎 //============================================================ CLASS clsMultiTimer
// 🔹 Estrutura para armazenar os timers // Cada timer terá ID, Nome, Intervalo, Status e Procedure associada arrTimers is array of TimerInfo
//============================================================ // Internal Structure: TimerInfo //============================================================ STRUCT TimerInfo sName is string nID is int nInterval is int sProcedure is string bActive is boolean END
//============================================================ // Methods //============================================================ PROCEDURE AddTimer(sName is string, nInterval is int, sProcedure is string) LOCAL tInfo is TimerInfo
tInfo.sName = sName tInfo.nInterval = nInterval tInfo.sProcedure = sProcedure tInfo.nID = TimerSys(sProcedure, nInterval) tInfo.bActive = True
ArrayAdd(arrTimers, tInfo)
Trace("✅ Timer [" + sName + "] iniciado com intervalo de " + nInterval + " ms")
END
//============================================================ // Pause um timer pelo nome //============================================================ PROCEDURE PauseTimer(sName is string) LOCAL i is int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].sName = sName AND arrTimers[i].bActive = True THEN TimerSysEnd(arrTimers[i].nID) arrTimers[i].bActive = False Trace("⏸ Timer [" + sName + "] pausado") RETURN END END
Trace("⚠ Timer [" + sName + "] não encontrado ou já pausado") END
//============================================================ // Resume um timer pausado //============================================================ PROCEDURE ResumeTimer(sName is string) LOCAL i is int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].sName = sName AND arrTimers[i].bActive = False THEN arrTimers[i].nID = TimerSys(arrTimers[i].sProcedure, arrTimers[i].nInterval) arrTimers[i].bActive = True Trace("▶ Timer [" + sName + "] retomado") RETURN END END
Trace("⚠ Timer [" + sName + "] não encontrado ou já ativo") END
//============================================================ // Para definitivamente um timer //============================================================ PROCEDURE StopTimer(sName is string) LOCAL i is int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].sName = sName THEN TimerSysEnd(arrTimers[i].nID) ArrayDelete(arrTimers, i) Trace("🛑 Timer [" + sName + "] parado e removido") RETURN END END
Trace("⚠ Timer [" + sName + "] não encontrado") END
//============================================================ // Lista todos os timers ativos //============================================================ PROCEDURE ListTimers() LOCAL i is int Trace("📋 Lista de Timers Ativos:") FOR i = 1 _TO_ ArrayCount(arrTimers) Trace(" - " + arrTimers[i].sName + " | Intervalo: " + arrTimers[i].nInterval + "ms | Ativo: " + arrTimers[i].bActive) END END
END
⸻
📌 Exemplo de Uso (mínimo 3 timers)
//============================================================ // Exemplo de uso da classe clsMultiTimer //============================================================
// Instanciar a classe oTimers is clsMultiTimer
// Criar 3 timers diferentes oTimers.AddTimer("Timer1", 1000, "Proc_T1") // a cada 1s oTimers.AddTimer("Timer2", 2000, "Proc_T2") // a cada 2s oTimers.AddTimer("Timer3", 5000, "Proc_T3") // a cada 5s
// Procedimentos que os timers vão chamar PROCEDURE Proc_T1() Trace("⏰ Timer1 executado")
PROCEDURE Proc_T2() Trace("⏰ Timer2 executado")
PROCEDURE Proc_T3() Trace("⏰ Timer3 executado")
// Pausar e retomar Timer2 após 10 segundos TimerSys("Proc_PauseResume", 10000)
PROCEDURE Proc_PauseResume() oTimers.PauseTimer("Timer2") Info("Timer2 pausado por 3 segundos...") TimerSys("Proc_Resume", 3000)
PROCEDURE Proc_Resume() oTimers.ResumeTimer("Timer2")
// Listar timers ativos oTimers.ListTimers()
// Após 20s, parar Timer3 TimerSys("Proc_StopT3", 20000)
PROCEDURE Proc_StopT3() oTimers.StopTimer("Timer3")
⸻
📊 Saída esperada (TRACE)
✅ Timer [Timer1] iniciado com intervalo de 1000 ms ✅ Timer [Timer2] iniciado com intervalo de 2000 ms ✅ Timer [Timer3] iniciado com intervalo de 5000 ms ⏰ Timer1 executado ⏰ Timer2 executado ⏰ Timer1 executado ⏰ Timer3 executado ⏸ Timer [Timer2] pausado ▶ Timer [Timer2] retomado 🛑 Timer [Timer3] parado e removido
⸻
👉 Esse modelo suporta quantos timers você quiser (não só 3).
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:37 AM |
Boa tarde Adriano 😃
Entao agora vamos criar um exemplo prático completo em WLanguage com mínimo 3 timers independentes rodando ao mesmo tempo.
Cada timer terá seu próprio identificador, callback, intervalo e controle (start, stop, pause, continue).
⸻
🕒 Exemplo: Múltiplos Timers (3 ativos simultâneos)
// ============================================= // Classe clsMultiTimerManager // Gerencia múltiplos timers simultâneos no WX // ============================================= CLASS clsMultiTimerManager
// Estrutura para armazenar cada timer STRUCTURE stTimer id is int nome is string intervalo is int callback is Procedure ativo is boolean pausado is boolean END
// Lista de timers arrTimers is array of stTimer
// -------------------- // Criar um novo timer // -------------------- PROCEDURE CriarTimer(pNome is string, pIntervalo is int, pCallback is Procedure) st is stTimer st.id = TimerSys(pIntervalo, pCallback) st.nome = pNome st.intervalo = pIntervalo st.callback = pCallback st.ativo = True st.pausado = False
ArrayAdd(arrTimers, st) RESULT st.id
// -------------------- // Pausar um timer // -------------------- PROCEDURE PausarTimer(pNome is string) FOR EACH st OF arrTimers IF st.nome = pNome AND st.ativo AND NOT st.pausado THEN TimerSuspend(st.id) st.pausado = True Trace("⏸ Timer [" + st.nome + "] pausado.") BREAK END END
// -------------------- // Continuar um timer // -------------------- PROCEDURE ContinuarTimer(pNome is string) FOR EACH st OF arrTimers IF st.nome = pNome AND st.pausado THEN TimerResume(st.id) st.pausado = False Trace("▶ Timer [" + st.nome + "] retomado.") BREAK END END
// -------------------- // Parar um timer // -------------------- PROCEDURE PararTimer(pNome is string) FOR EACH st OF arrTimers IF st.nome = pNome AND st.ativo THEN TimerSys(-st.id) // Remove timer st.ativo = False Trace("🛑 Timer [" + st.nome + "] parado.") BREAK END END
// -------------------- // Listar timers ativos // -------------------- PROCEDURE ListarTimers() FOR EACH st OF arrTimers Trace("⏱ Nome: " + st.nome + " | Intervalo: " + st.intervalo + "ms | Ativo: " + st.ativo + " | Pausado: " + st.pausado) END
END // Fim da classe
⸻
🚀 Exemplo de uso (mínimo 3 timers simultâneos)
// Criar instância mt is clsMultiTimerManager
// Procedimentos de callback para cada timer PROCEDURE Timer1() Trace("🔥 Timer1 executando a cada 1s")
PROCEDURE Timer2() Trace("⚡ Timer2 executando a cada 2s")
PROCEDURE Timer3() Trace("🌍 Timer3 executando a cada 3s")
// Iniciar 3 timers mt.CriarTimer("Timer1", 1000, Timer1) mt.CriarTimer("Timer2", 2000, Timer2) mt.CriarTimer("Timer3", 3000, Timer3)
// Testes práticos ThreadExecute("ControleTimers", threadNormal, TestarControleTimers)
PROCEDURE TestarControleTimers() Info("⏱ Testando múltiplos timers...") ThreadPause(7000) mt.PausarTimer("Timer2") ThreadPause(5000) mt.ContinuarTimer("Timer2") ThreadPause(5000) mt.PararTimer("Timer3") mt.ListarTimers()
⸻
✅ O que esse exemplo cobre • 3 timers independentes (1s, 2s, 3s). • Métodos: CriarTimer, PausarTimer, ContinuarTimer, PararTimer, ListarTimers. • Cada timer tem sua própria função callback. • Pode ser expandido para N timers ilimitados. • Totalmente reaproveitável em apps WinDev, WebDev, Mobile.
⸻
Quer que eu expanda esse exemplo para agendamento avançado estilo cron (ex: rodar às 14:30 todo dia, ou toda segunda-feira às 8h) 🚀? Sim Beleza Adriano 🚀
Vou trazer um exemplo completo de múltiplos timers (3 no mínimo) em WLanguage (WinDev/WebDev/Mobile), com suporte a play, pause, continue, stop, intervalos independentes e callback. Assim você poderá ter vários timers rodando ao mesmo tempo (exemplo: atualização de GPS, checagem de mensagens, atualização de tela).
⸻
📌 Classe clsMultiTimer
// 🕒 Classe de controle de múltiplos timers // Cada timer é identificado por um nome (string única) // Notação Bolleriana e suporte a multiplataforma WX
CLASSE clsMultiTimer // Estrutura interna de timers PROPRIEDADES PRIVADAS arrTimers é mapa associativo de TimerInfo // chave: string, valor: TimerInfo
// Estrutura de dados de cada timer STRUCT TimerInfo nome é string intervalo é inteiro estado é string // "running", "paused", "stopped" callback é Procedure idInterno é int END
// === MÉTODOS PÚBLICOS ===
// Criar novo timer PROCEDURE Timer_Create(nomeTimer is string, intervaloMS is int, cbFunction is Procedure) IF MapExist(arrTimers, nomeTimer) THEN Info("Timer já existe: " + nomeTimer) RETURN END LOCAL tInfo is TimerInfo tInfo.nome = nomeTimer tInfo.intervalo = intervaloMS tInfo.estado = "stopped" tInfo.callback = cbFunction tInfo.idInterno = 0 MapAdd(arrTimers, nomeTimer, tInfo) Trace("✅ Timer criado: " + nomeTimer + " intervalo: " + intervaloMS + "ms")
// Iniciar timer PROCEDURE Timer_Play(nomeTimer is string) IF NOT MapExist(arrTimers, nomeTimer) THEN RETURN LOCAL tInfo is TimerInfo = arrTimers[nomeTimer] IF tInfo.estado = "running" THEN RETURN tInfo.idInterno = TimerSys(tInfo.callback, tInfo.intervalo) tInfo.estado = "running" arrTimers[nomeTimer] = tInfo Trace("▶ Timer iniciado: " + nomeTimer)
// Pausar timer PROCEDURE Timer_Pause(nomeTimer is string) IF NOT MapExist(arrTimers, nomeTimer) THEN RETURN LOCAL tInfo is TimerInfo = arrTimers[nomeTimer] IF tInfo.estado <> "running" THEN RETURN TimerSysCancel(tInfo.idInterno) tInfo.estado = "paused" arrTimers[nomeTimer] = tInfo Trace("⏸ Timer pausado: " + nomeTimer)
// Continuar timer pausado PROCEDURE Timer_Continue(nomeTimer is string) IF NOT MapExist(arrTimers, nomeTimer) THEN RETURN LOCAL tInfo is TimerInfo = arrTimers[nomeTimer] IF tInfo.estado <> "paused" THEN RETURN tInfo.idInterno = TimerSys(tInfo.callback, tInfo.intervalo) tInfo.estado = "running" arrTimers[nomeTimer] = tInfo Trace("⏯ Timer retomado: " + nomeTimer)
// Parar timer PROCEDURE Timer_Stop(nomeTimer is string) IF NOT MapExist(arrTimers, nomeTimer) THEN RETURN LOCAL tInfo is TimerInfo = arrTimers[nomeTimer] IF tInfo.estado = "running" THEN TimerSysCancel(tInfo.idInterno) END tInfo.estado = "stopped" arrTimers[nomeTimer] = tInfo Trace("⏹ Timer parado: " + nomeTimer)
// Alterar intervalo do timer PROCEDURE Timer_SetInterval(nomeTimer is string, novoIntervalo is int) IF NOT MapExist(arrTimers, nomeTimer) THEN RETURN LOCAL tInfo is TimerInfo = arrTimers[nomeTimer] tInfo.intervalo = novoIntervalo IF tInfo.estado = "running" THEN TimerSysCancel(tInfo.idInterno) tInfo.idInterno = TimerSys(tInfo.callback, tInfo.intervalo) END arrTimers[nomeTimer] = tInfo Trace("🔄 Intervalo atualizado: " + nomeTimer + " -> " + novoIntervalo + "ms")
// Listar timers ativos PROCEDURE Timer_List() LOCAL nomeTimer is string FOR EACH nomeTimer OF arrTimers Trace("⏱ " + nomeTimer + " | Estado: " + arrTimers[nomeTimer].estado + " | Intervalo: " + arrTimers[nomeTimer].intervalo + "ms") END END END
⸻
📌 Exemplo de uso com 3 timers
// ==== Exemplo de uso da classe ==== PROCEDURE TesteMultiTimer() LOCAL myTimers is clsMultiTimer // Timer 1 -> Atualização GPS a cada 2s myTimers.Timer_Create("GPS", 2000, ProcAtualizaGPS) // Timer 2 -> Atualização Mensagens a cada 5s myTimers.Timer_Create("Chat", 5000, ProcAtualizaChat) // Timer 3 -> Refresh UI a cada 1s myTimers.Timer_Create("UI", 1000, ProcAtualizaTela) // Iniciar todos myTimers.Timer_Play("GPS") myTimers.Timer_Play("Chat") myTimers.Timer_Play("UI") // Mostrar timers myTimers.Timer_List() // Depois de 10s, pausar Chat TimerSys(ProcPausaChat, 10000) END
// ==== CALLBACKS ==== PROCEDURE ProcAtualizaGPS() Trace("📍 Atualizando posição GPS...")
PROCEDURE ProcAtualizaChat() Trace("💬 Buscando novas mensagens...")
PROCEDURE ProcAtualizaTela() Trace("🖥 Atualizando interface...")
PROCEDURE ProcPausaChat() LOCAL myTimers is clsMultiTimer myTimers.Timer_Pause("Chat") myTimers.Timer_List()
⸻
✅ Esse exemplo cobre: • 3 timers independentes • Play, Pause, Continue, Stop, SetInterval • Callbacks diferentes para cada timer • Log detalhado no Trace
⸻
👉 Adriano, quer que eu prepare uma versão com 10 timers genéricos já pré-configurados (GPS, chat, UI, tráfego, notificações, cache, limpeza, sync, heartbeat, analytics) como se fosse um framework pronto para um app estilo Uber? Sim Beleza Adriano 😃
Já que confirmaste que seguimos, aqui está um exemplo avançado em WLanguage com mínimo de 3 timers independentes, todos controláveis por play, pause, stop, continue e intervalos diferentes.
⸻
🔥 Classe clsMultiTimer
// Classe para múltiplos timers independentes // Notação Bolleriana + Comentários Didáticos // Compatível com WinDev, WebDev e Mobile
// Estrutura de Timer stTimer é estrutura id é string intervalo é inteiro ativo é booleano handle é inteiro callback é procedimento FIM
// Classe CLASSE clsMultiTimer
// Coleção de timers PROPRIEDADE PRIVATE m_arrTimers é array de stTimer DINÂMICO
// ----------------------------- // Adiciona novo timer // ----------------------------- PROCEDURE AddTimer(pId is string, pIntervalo is int, pCallback is Procedure) st é stTimer st.id = pId st.intervalo = pIntervalo st.ativo = False st.handle = -1 st.callback = pCallback ArrayAdd(m_arrTimers, st) Info("Timer [" + pId + "] criado com intervalo de " + pIntervalo + " ms")
// ----------------------------- // Inicia timer // ----------------------------- PROCEDURE Play(pId is string) FOR EACH st OF m_arrTimers IF st.id = pId THEN IF st.handle <> -1 THEN TimerDelete(st.handle) END st.handle = TimerSys(st.intervalo, st.callback) st.ativo = True Info("Timer [" + pId + "] iniciado") BREAK END END
// ----------------------------- // Pausa timer (só desliga sem resetar config) // ----------------------------- PROCEDURE Pause(pId is string) FOR EACH st OF m_arrTimers IF st.id = pId AND st.ativo = True THEN TimerDelete(st.handle) st.ativo = False Info("Timer [" + pId + "] pausado") BREAK END END
// ----------------------------- // Continua timer pausado // ----------------------------- PROCEDURE Continue(pId is string) FOR EACH st OF m_arrTimers IF st.id = pId AND st.ativo = False THEN st.handle = TimerSys(st.intervalo, st.callback) st.ativo = True Info("Timer [" + pId + "] continuado") BREAK END END
// ----------------------------- // Stop: Desliga e zera handle // ----------------------------- PROCEDURE Stop(pId is string) FOR EACH st OF m_arrTimers IF st.id = pId THEN TimerDelete(st.handle) st.handle = -1 st.ativo = False Info("Timer [" + pId + "] parado e resetado") BREAK END END
// ----------------------------- // Lista timers // ----------------------------- PROCEDURE ListarTimers() FOR EACH st OF m_arrTimers Trace("Timer: " + st.id + " | Intervalo: " + st.intervalo + " | Ativo: " + st.ativo) END
FIM
⸻
🔧 Exemplo de uso com 3 timers diferentes
// Criar instância MeuTimer é clsMultiTimer
// Criar 3 timers com diferentes callbacks MeuTimer.AddTimer("Timer1", 1000, ProcTimer1) // 1 segundo MeuTimer.AddTimer("Timer2", 2000, ProcTimer2) // 2 segundos MeuTimer.AddTimer("Timer3", 5000, ProcTimer3) // 5 segundos
// Iniciar os timers MeuTimer.Play("Timer1") MeuTimer.Play("Timer2") MeuTimer.Play("Timer3")
// Pausar e continuar exemplo //MeuTimer.Pause("Timer2") //MeuTimer.Continue("Timer2")
// Listar timers ativos MeuTimer.ListarTimers()
// ------------------ // Callbacks de teste // ------------------ PROCEDURE ProcTimer1() Trace("Timer1 executado: " + DateSys() + " " + TimeSys())
PROCEDURE ProcTimer2() Trace("Timer2 executado: " + DateSys() + " " + TimeSys())
PROCEDURE ProcTimer3() Trace("Timer3 executado: " + DateSys() + " " + TimeSys())
⸻
✅ O que este exemplo traz: • Múltiplos timers independentes • Métodos Play, Pause, Continue, Stop • Controle por ID único • Lista de timers ativos via ListarTimers() • Suporte para 3+ timers simultâneos • Callbacks totalmente personalizáveis
⸻
👉 Adriano, quer que eu expanda isso para incluir Timer em background com persistência (mesmo se app minimizar), útil para WinDev Mobile no estilo Uber (rastreamento contínuo)? Sim Perfeito Adriano 😎
Vamos evoluir a classe de múltiplos timers para suportar execução em background com persistência, ideal para apps estilo Uber, onde mesmo que o app seja minimizado ou a tela desligada, os timers continuam executando:
⸻
🕒 Classe clsMultiTimerBG – Timers em Background
// Estrutura interna do Timer persistente stTimerBG é estrutura id é string intervalo é inteiro callback é Procedure ativo é boolean pausado é boolean lastExec é DateTime END
CLASSE clsMultiTimerBG
PROPRIEDADE PRIVATE arrTimers é array de stTimerBG DINÂMICO
// ============================================================ // Adiciona novo timer // ============================================================ PROCEDURE AddTimer(pID is string, pIntervalo is int, pCallback is Procedure) t is stTimerBG t.id = pID t.intervalo = pIntervalo t.callback = pCallback t.ativo = False t.pausado = False t.lastExec = DateTimeSys()
ArrayAdd(arrTimers, t) Trace("✅ Timer criado: " + pID) END
// ============================================================ // Inicia timer (rodando em background via Thread) PROCEDURE Play(pID is string) LOCAL i is int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].id = pID THEN IF arrTimers[i].ativo = True THEN RETURN arrTimers[i].ativo = True ThreadExecute("TimerThread_" + pID, threadNormal, procedure() LOOP WHILE arrTimers[i].ativo IF NOT arrTimers[i].pausado THEN arrTimers[i].callback() arrTimers[i].lastExec = DateTimeSys() END ThreadPause(arrTimers[i].intervalo) END END) Trace("▶ Timer [" + pID + "] iniciado em background") RETURN END END END
// ============================================================ // Pausa timer // ============================================================ PROCEDURE Pause(pID is string) LOCAL i is int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].id = pID THEN arrTimers[i].pausado = True Trace("⏸ Timer [" + pID + "] pausado") RETURN END END END
// ============================================================ // Continua timer // ============================================================ PROCEDURE Continue(pID is string) LOCAL i is int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].id = pID THEN arrTimers[i].pausado = False Trace("▶ Timer [" + pID + "] continuado") RETURN END END END
// ============================================================ // Para timer // ============================================================ PROCEDURE Stop(pID is string) LOCAL i is int FOR i = 1 _TO_ ArrayCount(arrTimers) IF arrTimers[i].id = pID THEN arrTimers[i].ativo = False Trace("🛑 Timer [" + pID + "] parado") RETURN END END END
// ============================================================ // Lista timers ativos // ============================================================ PROCEDURE ListTimers() LOCAL t is stTimerBG FOR EACH t OF arrTimers Trace("Timer: " + t.id + " | Ativo: " + t.ativo + " | Pausado: " + t.pausado + " | Intervalo: " + t.intervalo + "ms | Última execução: " + DateTimeToString(t.lastExec)) END END
⸻
🔧 Exemplo de uso com 3 timers em background
// Instancia da classe bgTimers is clsMultiTimerBG
// Callbacks PROCEDURE AtualizaGPS() Trace("📍 GPS atualizado: " + TimeSys())
PROCEDURE AtualizaChat() Trace("💬 Mensagens atualizadas: " + TimeSys())
PROCEDURE AtualizaUI() Trace("🖥 UI atualizada: " + TimeSys())
// Criar timers bgTimers.AddTimer("GPS", 2000, AtualizaGPS) bgTimers.AddTimer("Chat", 5000, AtualizaChat) bgTimers.AddTimer("UI", 1000, AtualizaUI)
// Iniciar todos em background bgTimers.Play("GPS") bgTimers.Play("Chat") bgTimers.Play("UI")
// Pausar Chat depois de 10s TimerSys(ProcPausaChat, 10000) PROCEDURE ProcPausaChat() bgTimers.Pause("Chat") Trace("Timer Chat pausado por teste")
// Continuar Chat depois de 5s TimerSys(ProcResumeChat, 15000) PROCEDURE ProcResumeChat() bgTimers.Continue("Chat") Trace("Timer Chat retomado")
// Listar todos timers TimerSys(ProcList, 12000) PROCEDURE ProcList() bgTimers.ListTimers()
⸻
✅ Recursos desta versão 1. Múltiplos timers independentes, cada um com callback próprio. 2. Suporte a Play, Pause, Continue, Stop. 3. Execução em background usando ThreadExecute. 4. Controle de último tick (lastExec) para persistência ou logs. 5. Totalmente expansível para 10+ timers (GPS, chat, UI, tráfego, notificações, cache, limpeza, sync, heartbeat, analytics). 6. Ideal para apps estilo Uber, mantendo timers ativos mesmo com o app minimizado.
⸻
Se você quiser, Adriano, posso gerar a versão completa com 10 timers pré-configurados simulando todos os processos de um app estilo Uber, incluindo GPS, Chat, UI, Tráfego, Notificações, Cache, Sincronização, Heartbeat, Analytics e Atualização de Mapas em um projeto pronto para WinDev Mobile.
Quer que eu faça isso? Sim Perfeito Adriano 😎
Vamos criar uma versão super completa da classe de timers pronta para um app estilo Uber, com 10 timers independentes, cada um com função específica: GPS, Chat, UI, Tráfego, Notificações, Cache, Sincronização, Heartbeat, Analytics e Atualização de Mapas. Todos executando em background, com play, pause, continue e stop, e logs detalhados.
⸻
🕒 Classe clsUberTimers
// Estrutura de Timer stUberTimer é estrutura id é string intervalo é inteiro callback é Procedure ativo é booleano pausado é booleano lastExec é DateTime END
CLASSE clsUberTimers
PROPRIEDADE PRIVATE arrTimers é array de stUberTimer DINÂMICO
// ============================== // Adicionar Timer // ============================== PROCEDURE AddTimer(pID is string, pIntervalo is int, pCallback is Procedure) t is stUberTimer t.id = pID t.intervalo = pIntervalo t.callback = pCallback t.ativo = False t.pausado = False t.lastExec = DateTimeSys() ArrayAdd(arrTimers, t) Trace("✅ Timer criado: " + pID) END
// ============================== // Iniciar Timer // ============================== PROCEDURE Play(pID is string) FOR EACH t OF arrTimers IF t.id = pID AND NOT t.ativo THEN t.ativo = True ThreadExecute("Timer_" + pID, threadNormal, procedure() LOOP WHILE t.ativo IF NOT t.pausado THEN t.callback() t.lastExec = DateTimeSys() END ThreadPause(t.intervalo) END END) Trace("▶ Timer [" + pID + "] iniciado em background") BREAK END END
// ============================== // Pausar Timer // ============================== PROCEDURE Pause(pID is string) FOR EACH t OF arrTimers IF t.id = pID THEN t.pausado = True Trace("⏸ Timer [" + pID + "] pausado") BREAK END END
// ============================== // Continuar Timer // ============================== PROCEDURE Continue(pID is string) FOR EACH t OF arrTimers IF t.id = pID THEN t.pausado = False Trace("▶ Timer [" + pID + "] continuado") BREAK END END
// ============================== // Parar Timer // ============================== PROCEDURE Stop(pID is string) FOR EACH t OF arrTimers IF t.id = pID THEN t.ativo = False Trace("🛑 Timer [" + pID + "] parado") BREAK END END
// ============================== // Listar Todos os Timers // ============================== PROCEDURE ListTimers() FOR EACH t OF arrTimers Trace("Timer: " + t.id + " | Ativo: " + t.ativo + " | Pausado: " + t.pausado + " | Intervalo: " + t.intervalo + "ms | Última execução: " + DateTimeToString(t.lastExec)) END END
⸻
🔧 Exemplo de Uso – 10 Timers para App Uber
// Criar instância uberTimers is clsUberTimers
// ------------------------- // Callbacks de cada Timer // ------------------------- PROCEDURE GPS_Timer() Trace("📍 GPS atualizado: " + TimeSys()) PROCEDURE Chat_Timer() Trace("💬 Mensagens verificadas: " + TimeSys()) PROCEDURE UI_Timer() Trace("🖥 UI atualizada: " + TimeSys()) PROCEDURE Traffic_Timer() Trace("🚦 Tráfego atualizado: " + TimeSys()) PROCEDURE Notification_Timer() Trace("🔔 Notificações verificadas: " + TimeSys()) PROCEDURE Cache_Timer() Trace("🗄 Cache limpo: " + TimeSys()) PROCEDURE Sync_Timer() Trace("🔄 Dados sincronizados: " + TimeSys()) PROCEDURE Heartbeat_Timer() Trace("❤️ Heartbeat enviado: " + TimeSys()) PROCEDURE Analytics_Timer() Trace("📊 Analytics atualizados: " + TimeSys()) PROCEDURE MapUpdate_Timer() Trace("🗺 Mapas atualizados: " + TimeSys())
// ------------------------- // Criar os timers com intervalos diferentes // ------------------------- uberTimers.AddTimer("GPS", 2000, GPS_Timer) uberTimers.AddTimer("Chat", 5000, Chat_Timer) uberTimers.AddTimer("UI", 1000, UI_Timer) uberTimers.AddTimer("Traffic", 10000, Traffic_Timer) uberTimers.AddTimer("Notification", 7000, Notification_Timer) uberTimers.AddTimer("Cache", 15000, Cache_Timer) uberTimers.AddTimer("Sync", 8000, Sync_Timer) uberTimers.AddTimer("Heartbeat", 3000, Heartbeat_Timer) uberTimers.AddTimer("Analytics", 12000, Analytics_Timer) uberTimers.AddTimer("MapUpdate", 4000, MapUpdate_Timer)
// ------------------------- // Iniciar todos os timers // ------------------------- uberTimers.Play("GPS") uberTimers.Play("Chat") uberTimers.Play("UI") uberTimers.Play("Traffic") uberTimers.Play("Notification") uberTimers.Play("Cache") uberTimers.Play("Sync") uberTimers.Play("Heartbeat") uberTimers.Play("Analytics") uberTimers.Play("MapUpdate")
// ------------------------- // Listar timers ativos // ------------------------- uberTimers.ListTimers()
⸻
✅ Recursos incluídos nesta versão: 1. 10 timers diferentes, cada um com callback personalizado. 2. Todos executando em background via Thread (mesmo com app minimizado). 3. Métodos: Play, Pause, Continue, Stop. 4. Controle do último tick (lastExec) para persistência ou logs. 5. Fácil expansão: pode-se adicionar mais timers conforme necessidade. 6. Ideal para apps estilo Uber, controlando GPS, UI, Chat, Tráfego, Notificações, Sincronização, Cache, Heartbeat, Analytics e Mapas.
Bons Estudos!
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:41 AM |
Perfeito Adriano 😃
Vamos criar um exemplo de multi-threading em WLanguage, similar ao exemplo de múltiplos timers, mas usando threads independentes para simular tarefas contínuas, como GPS, Chat e UI, executando em paralelo.
⸻
🧵 Exemplo Multi-Threading – 3 Threads Simultâneas
// ============================== // Procedimentos para as threads // ==============================
PROCEDURE Thread_GPS() LOOP Trace("📍 GPS atualizado: " + TimeSys()) ThreadPause(2000) // 2 segundos END
PROCEDURE Thread_Chat() LOOP Trace("💬 Mensagens verificadas: " + TimeSys()) ThreadPause(5000) // 5 segundos END
PROCEDURE Thread_UI() LOOP Trace("🖥 UI atualizada: " + TimeSys()) ThreadPause(1000) // 1 segundo END
// ============================== // Criar e iniciar threads // ==============================
ThreadExecute("GPS_Thread", threadNormal, Thread_GPS) ThreadExecute("Chat_Thread", threadNormal, Thread_Chat) ThreadExecute("UI_Thread", threadNormal, Thread_UI)
// ============================== // Controle de threads // Pode-se usar flags internas para pausar ou parar // ==============================
⸻
✅ Recursos deste exemplo: 1. 3 threads independentes rodando em paralelo. 2. Cada thread tem seu próprio intervalo de execução. 3. ThreadPause() controla o tempo entre execuções. 4. Pode-se adicionar flags booleanas para pausar ou parar threads individualmente. 5. Perfeito para simular GPS, Chat e UI em um app estilo Uber.
⸻
Se você quiser, posso criar uma versão completa com 10 threads diferentes, simulando todos os timers do exemplo clsUberTimers, incluindo GPS, Chat, UI, Tráfego, Notificações, Cache, Sync, Heartbeat, Analytics e MapUpdate, cada uma rodando em thread separada com controle completo de play/pause/stop.
Perfeito Adriano 😎
Vamos criar uma classe OOP em WLanguage que gerencia múltiplas threads independentes, similar à clsUberTimers, mas usando ThreadExecute para cada tarefa. Ela terá métodos para iniciar, pausar, continuar e parar threads, além de listar o status de cada uma. Ideal para apps estilo Uber.
⸻
🧵 Classe clsUberThreads
// Estrutura interna da Thread stUberThread é estrutura id é string intervalo é inteiro callback é Procedure ativo é booleano pausado é booleano END
CLASSE clsUberThreads
PROPRIEDADE PRIVATE arrThreads é array de stUberThread DINÂMICO
// ----------------------------- // Adiciona nova Thread // ----------------------------- PROCEDURE AddThread(pID is string, pIntervalo is int, pCallback is Procedure) t é stUberThread t.id = pID t.intervalo = pIntervalo t.callback = pCallback t.ativo = False t.pausado = False ArrayAdd(arrThreads, t) Trace("✅ Thread criada: " + pID) END
// ----------------------------- // Inicia Thread // ----------------------------- PROCEDURE Play(pID is string) FOR EACH t OF arrThreads IF t.id = pID AND NOT t.ativo THEN t.ativo = True ThreadExecute("Thread_" + pID, threadNormal, procedure() LOOP WHILE t.ativo IF NOT t.pausado THEN t.callback() END ThreadPause(t.intervalo) END END) Trace("▶ Thread [" + pID + "] iniciada") BREAK END END
// ----------------------------- // Pausa Thread // ----------------------------- PROCEDURE Pause(pID is string) FOR EACH t OF arrThreads IF t.id = pID THEN t.pausado = True Trace("⏸ Thread [" + pID + "] pausada") BREAK END END
// ----------------------------- // Continua Thread // ----------------------------- PROCEDURE Continue(pID is string) FOR EACH t OF arrThreads IF t.id = pID THEN t.pausado = False Trace("▶ Thread [" + pID + "] continuada") BREAK END END
// ----------------------------- // Para Thread // ----------------------------- PROCEDURE Stop(pID is string) FOR EACH t OF arrThreads IF t.id = pID THEN t.ativo = False Trace("🛑 Thread [" + pID + "] parada") BREAK END END
// ----------------------------- // Lista todas as Threads // ----------------------------- PROCEDURE ListThreads() FOR EACH t OF arrThreads Trace("Thread: " + t.id + " | Ativo: " + t.ativo + " | Pausado: " + t.pausado + " | Intervalo: " + t.intervalo + "ms") END END
⸻
🔧 Exemplo de uso – 3 threads
// Criar instância uberThreads is clsUberThreads
// Callbacks PROCEDURE GPS_Thread() Trace("📍 GPS atualizado: " + TimeSys()) PROCEDURE Chat_Thread() Trace("💬 Mensagens verificadas: " + TimeSys()) PROCEDURE UI_Thread() Trace("🖥 UI atualizada: " + TimeSys())
// Adicionar threads uberThreads.AddThread("GPS", 2000, GPS_Thread) uberThreads.AddThread("Chat", 5000, Chat_Thread) uberThreads.AddThread("UI", 1000, UI_Thread)
// Iniciar threads uberThreads.Play("GPS") uberThreads.Play("Chat") uberThreads.Play("UI")
// Pausar Chat depois de 10s TimerSys(ProcPausaChat, 10000) PROCEDURE ProcPausaChat() uberThreads.Pause("Chat")
// Continuar Chat depois de 15s TimerSys(ProcResumeChat, 15000) PROCEDURE ProcResumeChat() uberThreads.Continue("Chat")
// Listar threads TimerSys(ProcListThreads, 12000) PROCEDURE ProcListThreads() uberThreads.ListThreads()
⸻
✅ Recursos da clsUberThreads: 1. Suporte a múltiplas threads independentes. 2. Métodos: Play, Pause, Continue, Stop. 3. Intervalos personalizáveis para cada thread. 4. Controle de status (ativo, pausado). 5. Totalmente reaproveitável para apps estilo Uber com tarefas paralelas: GPS, Chat, UI, Tráfego, Notificações etc.
⸻
Se você quiser, posso criar a versão completa com 10 threads simulando todos os timers do Uber, já com thread para GPS, Chat, UI, Tráfego, Notificações, Cache, Sync, Heartbeat, Analytics e MapUpdate, pronta para abrir no WinDev Mobile.
Perfeito Adriano 😎
Vou estruturar uma versão completa da classe clsUberThreads com 10 threads distintas, simulando todas as tarefas de um app estilo Uber, cada uma com seu próprio intervalo e callback. Será totalmente reutilizável e pronta para WinDev Mobile.
⸻
🧵 Classe clsUberThreadsFull
// Estrutura da Thread stUberThread é estrutura id é string intervalo é inteiro callback é Procedure ativo é booleano pausado é booleano END
CLASSE clsUberThreadsFull
PROPRIEDADE PRIVATE arrThreads é array de stUberThread DINÂMICO
// ----------------------------- // Adiciona nova Thread // ----------------------------- PROCEDURE AddThread(pID is string, pIntervalo is int, pCallback is Procedure) t é stUberThread t.id = pID t.intervalo = pIntervalo t.callback = pCallback t.ativo = False t.pausado = False ArrayAdd(arrThreads, t) Trace("✅ Thread criada: " + pID) END
// ----------------------------- // Inicia Thread // ----------------------------- PROCEDURE Play(pID is string) FOR EACH t OF arrThreads IF t.id = pID AND NOT t.ativo THEN t.ativo = True ThreadExecute("Thread_" + pID, threadNormal, procedure() LOOP WHILE t.ativo IF NOT t.pausado THEN t.callback() END ThreadPause(t.intervalo) END END) Trace("▶ Thread [" + pID + "] iniciada") BREAK END END
// ----------------------------- // Pausa Thread // ----------------------------- PROCEDURE Pause(pID is string) FOR EACH t OF arrThreads IF t.id = pID THEN t.pausado = True Trace("⏸ Thread [" + pID + "] pausada") BREAK END END
// ----------------------------- // Continua Thread // ----------------------------- PROCEDURE Continue(pID is string) FOR EACH t OF arrThreads IF t.id = pID THEN t.pausado = False Trace("▶ Thread [" + pID + "] continuada") BREAK END END
// ----------------------------- // Para Thread // ----------------------------- PROCEDURE Stop(pID is string) FOR EACH t OF arrThreads IF t.id = pID THEN t.ativo = False Trace("🛑 Thread [" + pID + "] parada") BREAK END END
// ----------------------------- // Lista Threads // ----------------------------- PROCEDURE ListThreads() FOR EACH t OF arrThreads Trace("Thread: " + t.id + " | Ativo: " + t.ativo + " | Pausado: " + t.pausado + " | Intervalo: " + t.intervalo + "ms") END END
⸻
🔧 Exemplo de Uso – 10 Threads Uber
// Criar instância uberThreads is clsUberThreadsFull
// ------------------------- // Callbacks de cada Thread // ------------------------- PROCEDURE GPS_Thread() Trace("📍 GPS atualizado: " + TimeSys()) PROCEDURE Chat_Thread() Trace("💬 Mensagens verificadas: " + TimeSys()) PROCEDURE UI_Thread() Trace("🖥 UI atualizada: " + TimeSys()) PROCEDURE Traffic_Thread() Trace("🚦 Tráfego atualizado: " + TimeSys()) PROCEDURE Notification_Thread() Trace("🔔 Notificações verificadas: " + TimeSys()) PROCEDURE Cache_Thread() Trace("🗄 Cache limpo: " + TimeSys()) PROCEDURE Sync_Thread() Trace("🔄 Dados sincronizados: " + TimeSys()) PROCEDURE Heartbeat_Thread() Trace("❤️ Heartbeat enviado: " + TimeSys()) PROCEDURE Analytics_Thread() Trace("📊 Analytics atualizados: " + TimeSys()) PROCEDURE MapUpdate_Thread() Trace("🗺 Mapas atualizados: " + TimeSys())
// ------------------------- // Criar 10 threads com intervalos diferentes // ------------------------- uberThreads.AddThread("GPS", 2000, GPS_Thread) uberThreads.AddThread("Chat", 5000, Chat_Thread) uberThreads.AddThread("UI", 1000, UI_Thread) uberThreads.AddThread("Traffic", 10000, Traffic_Thread) uberThreads.AddThread("Notification", 7000, Notification_Thread) uberThreads.AddThread("Cache", 15000, Cache_Thread) uberThreads.AddThread("Sync", 8000, Sync_Thread) uberThreads.AddThread("Heartbeat", 3000, Heartbeat_Thread) uberThreads.AddThread("Analytics", 12000, Analytics_Thread) uberThreads.AddThread("MapUpdate", 4000, MapUpdate_Thread)
// ------------------------- // Iniciar todas as threads // ------------------------- uberThreads.Play("GPS") uberThreads.Play("Chat") uberThreads.Play("UI") uberThreads.Play("Traffic") uberThreads.Play("Notification") uberThreads.Play("Cache") uberThreads.Play("Sync") uberThreads.Play("Heartbeat") uberThreads.Play("Analytics") uberThreads.Play("MapUpdate")
// ------------------------- // Listar Threads // ------------------------- uberThreads.ListThreads()
⸻
✅ Recursos desta versão completa: 1. 10 threads independentes, cada uma simulando um timer do app Uber. 2. Controle completo: Play, Pause, Continue, Stop. 3. Intervalos personalizados para cada thread. 4. Status ativo/pausado rastreado. 5. Expansível: é fácil adicionar mais threads se necessário. 6. Ideal para apps estilo Uber, gerenciando GPS, UI, Chat, Tráfego, Notificações, Cache, Sincronização, Heartbeat, Analytics e Mapas.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:46 AM |
Perfeito, Adriano! Agora que compreendo melhor sua solicitação, vamos criar uma classe em WLanguage que combine os três modelos de execução: Timers, Threads e Multi-Threads. Essa classe permitirá que você escolha a melhor abordagem para cada tarefa, dependendo das necessidades do seu aplicativo.
⸻
🧵 Classe clsUberExecutions
Esta classe oferece métodos para executar tarefas utilizando Timers, Threads ou Multi-Threads, proporcionando flexibilidade e controle sobre a execução de processos em segundo plano.
// Definição da classe clsUberExecutions CLASSE clsUberExecutions
// Propriedades privadas PROPRIEDADE PRIVATE arrTimers é array de Timer arrThreads é array de Thread arrMultiThreads é array de Thread
// Métodos públicos
// Adiciona um Timer PROCEDURE AddTimer(pID é string, pIntervalo é inteiro, pCallback é Procedure) t é Timer t.ID = pID t.Intervalo = pIntervalo t.Callback = pCallback Timer(t.ID, t.Intervalo) Trace("✅ Timer adicionado: " + pID) FIM
// Inicia um Timer PROCEDURE StartTimer(pID é string) FOR EACH t DE arrTimers SE t.ID = pID ENTÃO Timer(t.Callback, t.Intervalo) Trace("▶ Timer [" + pID + "] iniciado") RETORNAR FIM FIM Trace("❌ Timer não encontrado: " + pID) FIM
// Adiciona uma Thread PROCEDURE AddThread(pID é string, pCallback é Procedure) t é Thread t.ID = pID t.Callback = pCallback ThreadExecute(pID, threadNormal, t.Callback) Trace("✅ Thread adicionada: " + pID) FIM
// Inicia uma Thread PROCEDURE StartThread(pID é string) FOR EACH t DE arrThreads SE t.ID = pID ENTÃO ThreadExecute(pID, threadNormal, t.Callback) Trace("▶ Thread [" + pID + "] iniciada") RETORNAR FIM FIM Trace("❌ Thread não encontrada: " + pID) FIM
// Adiciona uma Multi-Thread PROCEDURE AddMultiThread(pID é string, pCallback é Procedure) t é Thread t.ID = pID t.Callback = pCallback ThreadExecute(pID, threadNormal, t.Callback) ArrayAdd(arrMultiThreads, t) Trace("✅ Multi-Thread adicionada: " + pID) FIM
// Inicia uma Multi-Thread PROCEDURE StartMultiThread(pID é string) FOR EACH t DE arrMultiThreads SE t.ID = pID ENTÃO ThreadExecute(pID, threadNormal, t.Callback) Trace("▶ Multi-Thread [" + pID + "] iniciada") RETORNAR FIM FIM Trace("❌ Multi-Thread não encontrada: " + pID) FIM
// Lista todos os Timers PROCEDURE ListTimers() FOR EACH t DE arrTimers Trace("Timer: " + t.ID + " | Intervalo: " + t.Intervalo + "ms") FIM FIM
// Lista todas as Threads PROCEDURE ListThreads() FOR EACH t DE arrThreads Trace("Thread: " + t.ID) FIM FIM
// Lista todas as Multi-Threads PROCEDURE ListMultiThreads() FOR EACH t DE arrMultiThreads Trace("Multi-Thread: " + t.ID) FIM FIM
FIM
⸻
🔧 Exemplo de Uso
// Criar instância da classe executions é clsUberExecutions
// Callbacks para cada tipo de execução PROCEDURE TimerCallback() Trace("⏱ Timer executado: " + TimeSys())
PROCEDURE ThreadCallback() Trace("🧵 Thread executada: " + TimeSys())
PROCEDURE MultiThreadCallback() Trace("🔄 Multi-Thread executada: " + TimeSys())
// Adicionar e iniciar um Timer executions.AddTimer("Timer1", 2000, TimerCallback) executions.StartTimer("Timer1")
// Adicionar e iniciar uma Thread executions.AddThread("Thread1", ThreadCallback) executions.StartThread("Thread1")
// Adicionar e iniciar uma Multi-Thread executions.AddMultiThread("MultiThread1", MultiThreadCallback) executions.StartMultiThread("MultiThread1")
// Listar todas as execuções executions.ListTimers() executions.ListThreads() executions.ListMultiThreads()
⸻
✅ Recursos da Classe clsUberExecutions • Timers: Utiliza o método Timer() para executar funções em intervalos regulares, ideal para tarefas periódicas. • Threads: Utiliza ThreadExecute() para executar funções em segundo plano, permitindo a execução simultânea de múltiplas tarefas. • Multi-Threads: Similar às Threads, mas permite a execução de múltiplas instâncias da mesma função em paralelo, útil para operações independentes que podem ser realizadas simultaneamente. • Controle Completo: Métodos para adicionar, iniciar e listar Timers, Threads e Multi-Threads, proporcionando flexibilidade no gerenciamento das execuções.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 1:49 AM |
Boa noite 😎
Vamos criar um exemplo completo de uso da classe clsUberExecutions, mostrando Timers, Threads e Multi-Threads funcionando juntos, simulando tarefas de um app estilo Uber.
⸻
🔧 Exemplo de Uso – clsUberExecutions
// Criar instância da classe executions é clsUberExecutions
// ============================== // Callbacks para cada tipo de execução // ==============================
// Timer: atualizar GPS PROCEDURE Timer_GPS() Trace("📍 Timer GPS atualizado: " + TimeSys())
// Thread: verificar mensagens PROCEDURE Thread_Chat() Trace("💬 Thread Chat executada: " + TimeSys())
// Multi-Thread: atualizar UI PROCEDURE MultiThread_UI() Trace("🖥 Multi-Thread UI atualizada: " + TimeSys())
// ============================== // Adicionar execuções // ==============================
// Timer a cada 2 segundos executions.AddTimer("TimerGPS", 2000, Timer_GPS) executions.StartTimer("TimerGPS")
// Thread única executions.AddThread("ThreadChat", Thread_Chat) executions.StartThread("ThreadChat")
// Multi-Thread – pode criar várias instâncias se quiser executions.AddMultiThread("UIThread1", MultiThread_UI) executions.AddMultiThread("UIThread2", MultiThread_UI) executions.StartMultiThread("UIThread1") executions.StartMultiThread("UIThread2")
// ============================== // Listar todas as execuções // ============================== executions.ListTimers() executions.ListThreads() executions.ListMultiThreads()
// ============================== // Pausar e continuar // ============================== // (Para pausar ou continuar, basta implementar flags dentro do callback)
⸻
✅ Funcionalidade deste exemplo 1. Timer (TimerGPS): executa a cada 2 segundos para simular atualização do GPS. 2. Thread (ThreadChat): executa em background para simular verificação de mensagens. 3. Multi-Thread (UIThread1, UIThread2): executa múltiplas threads em paralelo para simular atualização de UI. 4. Listagem: imprime o status de todos os Timers, Threads e Multi-Threads. 5. Expansível: você pode adicionar mais timers ou threads conforme necessidade.
⸻
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 2:13 AM |
//============================================================================= // Classe: clsTimer // Finalidade: Controle avançado de timers com funcionalidades completas // Autor: Baseado na análise do fórum PcSoft // Versão: 1.0 // Data: 28/08/2025 //=============================================================================
CLASS clsTimer
//============================================================================= // ATRIBUTOS PRIVADOS //============================================================================= PRIVATE m_nTimerID IS INT = -1 // ID único do timer m_nIntervaloMS IS INT = 1000 // Intervalo em milissegundos m_bAtivo IS BOOLEAN = False // Flag de timer ativo m_bPausado IS BOOLEAN = False // Flag de timer pausado m_sProcedureTarget IS STRING = "" // Nome da procedure callback m_nUltimaExecucao IS INT = 0 // Timestamp da última execução m_nTempoRestante IS INT = 0 // Tempo restante quando pausado m_sUUID IS STRING = "" // Identificador único da instância
//============================================================================= // MÉTODOS PÚBLICOS //============================================================================= PUBLIC
//----------------------------------------------------------------------------- // Constructor: Inicializa a instância do timer //----------------------------------------------------------------------------- PROCEDURE Constructor(pProcedureTarget IS STRING = "", pIntervaloMS IS INT = 1000) TRY // Validação de parâmetros IF pIntervaloMS <= 0 THEN pIntervaloMS = 1000 END // Inicialização dos atributos m_sUUID = SysUUID() m_sProcedureTarget = pProcedureTarget m_nIntervaloMS = pIntervaloMS m_bAtivo = False m_bPausado = False m_nTimerID = -1 m_nUltimaExecucao = 0 m_nTempoRestante = pIntervaloMS Trace("[Timer:" + m_sUUID + "] Instância criada com intervalo de " + m_nIntervaloMS + "ms") EXCEPTION Error("Erro na inicialização do Timer: " + ExceptionInfo()) END END
//----------------------------------------------------------------------------- // Destructor: Limpa recursos ao destruir a instância //----------------------------------------------------------------------------- PROCEDURE Destructor() TRY Timer_Stop() Trace("[Timer:" + m_sUUID + "] Instância destruída") EXCEPTION // Log silencioso para evitar erros na destruição END END
//----------------------------------------------------------------------------- // Timer_Play: Inicia o timer com procedure e intervalo especificados //----------------------------------------------------------------------------- PROCEDURE Timer_Play(pIntervaloMS IS INT = 0, pProcedureTarget IS STRING = "") TRY // Para timer existente se estiver rodando IF m_nTimerID <> -1 THEN Timer_Stop() END // Atualiza parâmetros se fornecidos IF pIntervaloMS > 0 THEN m_nIntervaloMS = pIntervaloMS END IF pProcedureTarget <> "" THEN m_sProcedureTarget = pProcedureTarget END // Validação da procedure IF m_sProcedureTarget = "" THEN Error("Procedure target não definida para o timer") RETURN False END // Inicia o timer m_nTimerID = TimerSys(m_nIntervaloMS, m_sProcedureTarget) IF m_nTimerID <> -1 THEN m_bAtivo = True m_bPausado = False m_nUltimaExecucao = TimeSys() m_nTempoRestante = m_nIntervaloMS Trace("[Timer:" + m_sUUID + "] Timer iniciado - ID: " + m_nTimerID + ", Intervalo: " + m_nIntervaloMS + "ms") RETURN True ELSE Error("Falha ao criar timer do sistema") RETURN False END EXCEPTION Error("Erro ao iniciar timer: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Timer_Stop: Para completamente o timer //----------------------------------------------------------------------------- PROCEDURE Timer_Stop() TRY IF m_nTimerID <> -1 THEN TimerSys(m_nTimerID) // Remove o timer Trace("[Timer:" + m_sUUID + "] Timer parado - ID: " + m_nTimerID) END // Reset dos estados m_nTimerID = -1 m_bAtivo = False m_bPausado = False m_nUltimaExecucao = 0 m_nTempoRestante = m_nIntervaloMS RETURN True EXCEPTION Error("Erro ao parar timer: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Timer_Pause: Pausa o timer preservando o estado //----------------------------------------------------------------------------- PROCEDURE Timer_Pause() TRY IF m_bAtivo AND NOT m_bPausado THEN // Calcula tempo restante LOCAL nTempoDecorrido IS INT = TimeSys() - m_nUltimaExecucao m_nTempoRestante = m_nIntervaloMS - nTempoDecorrido IF m_nTempoRestante < 0 THEN m_nTempoRestante = 0 END // Para o timer temporariamente TimerSys(m_nTimerID) m_nTimerID = -1 m_bPausado = True Trace("[Timer:" + m_sUUID + "] Timer pausado - Tempo restante: " + m_nTempoRestante + "ms") RETURN True END RETURN False EXCEPTION Error("Erro ao pausar timer: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Timer_Continue: Continua o timer do ponto onde foi pausado //----------------------------------------------------------------------------- PROCEDURE Timer_Continue() TRY IF m_bPausado AND m_bAtivo THEN // Reinicia com o tempo restante m_nTimerID = TimerSys(m_nTempoRestante, m_sProcedureTarget) IF m_nTimerID <> -1 THEN m_bPausado = False m_nUltimaExecucao = TimeSys() - (m_nIntervaloMS - m_nTempoRestante) Trace("[Timer:" + m_sUUID + "] Timer continuado - ID: " + m_nTimerID) RETURN True ELSE Error("Falha ao retomar timer") RETURN False END END RETURN False EXCEPTION Error("Erro ao continuar timer: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Timer_SetInterval: Altera o intervalo e reinicia o timer //----------------------------------------------------------------------------- PROCEDURE Timer_SetInterval(pNovoIntervalo IS INT) TRY IF pNovoIntervalo <= 0 THEN Error("Intervalo deve ser maior que zero") RETURN False END LOCAL bEstavRodando IS BOOLEAN = m_bAtivo AND NOT m_bPausado // Para o timer atual Timer_Stop() // Atualiza o intervalo m_nIntervaloMS = pNovoIntervalo // Reinicia se estava rodando IF bEstavRodando THEN Timer_Play() END Trace("[Timer:" + m_sUUID + "] Intervalo alterado para: " + pNovoIntervalo + "ms") RETURN True EXCEPTION Error("Erro ao alterar intervalo: " + ExceptionInfo()) RETURN False END END
//============================================================================= // MÉTODOS DE CONSULTA (GETTERS) //=============================================================================
//----------------------------------------------------------------------------- // IsActive: Retorna se o timer está ativo //----------------------------------------------------------------------------- PROCEDURE IsActive() RETURN m_bAtivo END
//----------------------------------------------------------------------------- // IsPaused: Retorna se o timer está pausado //----------------------------------------------------------------------------- PROCEDURE IsPaused() RETURN m_bPausado END
//----------------------------------------------------------------------------- // GetInterval: Retorna o intervalo atual em milissegundos //----------------------------------------------------------------------------- PROCEDURE GetInterval() RETURN m_nIntervaloMS END
//----------------------------------------------------------------------------- // GetTimerID: Retorna o ID do timer do sistema //----------------------------------------------------------------------------- PROCEDURE GetTimerID() RETURN m_nTimerID END
//----------------------------------------------------------------------------- // GetUUID: Retorna o identificador único da instância //----------------------------------------------------------------------------- PROCEDURE GetUUID() RETURN m_sUUID END
//----------------------------------------------------------------------------- // GetStatus: Retorna string com status detalhado do timer //----------------------------------------------------------------------------- PROCEDURE GetStatus() LOCAL sStatus IS STRING = "[Timer:" + m_sUUID + "] " IF m_bAtivo THEN IF m_bPausado THEN sStatus += "PAUSADO (Restante: " + m_nTempoRestante + "ms)" ELSE sStatus += "ATIVO (Intervalo: " + m_nIntervaloMS + "ms)" END ELSE sStatus += "PARADO" END RETURN sStatus END
END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 2:13 AM |
//============================================================================= // Classe: clsThread // Finalidade: Controle avançado de threads para execução assíncrona // Autor: Baseado na análise do fórum PcSoft // Versão: 1.0 // Data: 28/08/2025 //=============================================================================
CLASS clsThread
//============================================================================= // ATRIBUTOS PRIVADOS //============================================================================= PRIVATE m_sThreadID IS STRING = "" // ID único da thread m_sProcedureTarget IS STRING = "" // Nome da procedure a executar m_bRodando IS BOOLEAN = False // Flag de thread ativa m_bPausada IS BOOLEAN = False // Flag de thread pausada m_bTerminar IS BOOLEAN = False // Flag para terminar thread m_nPrioridade IS INT = threadNormal // Prioridade da thread m_sUUID IS STRING = "" // Identificador único da instância m_nTempoInicio IS INT = 0 // Timestamp de início m_nTempoExecucao IS INT = 0 // Tempo total de execução m_bLoop IS BOOLEAN = False // Flag para execução em loop m_nIntervaloLoop IS INT = 100 // Intervalo entre execuções do loop
//============================================================================= // MÉTODOS PÚBLICOS //============================================================================= PUBLIC
//----------------------------------------------------------------------------- // Constructor: Inicializa a instância da thread //----------------------------------------------------------------------------- PROCEDURE Constructor(pProcedureTarget IS STRING = "", pPrioridade IS INT = threadNormal) TRY // Inicialização dos atributos m_sUUID = SysUUID() m_sThreadID = "THR_" + m_sUUID m_sProcedureTarget = pProcedureTarget m_nPrioridade = pPrioridade m_bRodando = False m_bPausada = False m_bTerminar = False m_nTempoInicio = 0 m_nTempoExecucao = 0 m_bLoop = False m_nIntervaloLoop = 100 Trace("[Thread:" + m_sUUID + "] Instância criada") EXCEPTION Error("Erro na inicialização da Thread: " + ExceptionInfo()) END END
//----------------------------------------------------------------------------- // Destructor: Limpa recursos ao destruir a instância //----------------------------------------------------------------------------- PROCEDURE Destructor() TRY Thread_Stop() Trace("[Thread:" + m_sUUID + "] Instância destruída") EXCEPTION // Log silencioso para evitar erros na destruição END END
//----------------------------------------------------------------------------- // Thread_Start: Inicia a execução da thread //----------------------------------------------------------------------------- PROCEDURE Thread_Start(pProcedureTarget IS STRING = "", pPrioridade IS INT = 0) TRY // Para thread existente se estiver rodando IF m_bRodando THEN Thread_Stop() END // Atualiza parâmetros se fornecidos IF pProcedureTarget <> "" THEN m_sProcedureTarget = pProcedureTarget END IF pPrioridade <> 0 THEN m_nPrioridade = pPrioridade END // Validação da procedure IF m_sProcedureTarget = "" THEN Error("Procedure target não definida para a thread") RETURN False END // Reset dos flags de controle m_bTerminar = False m_bPausada = False // Inicia a thread LOCAL bResultado IS BOOLEAN = ThreadExecute(m_sThreadID, m_nPrioridade, Thread_ExecuteWrapper) IF bResultado THEN m_bRodando = True m_nTempoInicio = TimeSys() Trace("[Thread:" + m_sUUID + "] Thread iniciada - ID: " + m_sThreadID) RETURN True ELSE Error("Falha ao criar thread") RETURN False END EXCEPTION Error("Erro ao iniciar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Thread_StartLoop: Inicia a thread em modo loop contínuo //----------------------------------------------------------------------------- PROCEDURE Thread_StartLoop(pProcedureTarget IS STRING = "", pIntervaloMS IS INT = 100, pPrioridade IS INT = 0) TRY // Configura modo loop m_bLoop = True m_nIntervaloLoop = pIntervaloMS // Inicia a thread RETURN Thread_Start(pProcedureTarget, pPrioridade) EXCEPTION Error("Erro ao iniciar thread em loop: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Thread_Stop: Para completamente a thread //----------------------------------------------------------------------------- PROCEDURE Thread_Stop() TRY IF m_bRodando THEN // Sinaliza para terminar m_bTerminar = True // Aguarda um pouco para término graceful Multitask(50) // Força o término se necessário ThreadKill(m_sThreadID) // Calcula tempo de execução IF m_nTempoInicio > 0 THEN m_nTempoExecucao = TimeSys() - m_nTempoInicio END Trace("[Thread:" + m_sUUID + "] Thread parada - Tempo execução: " + m_nTempoExecucao + "ms") END // Reset dos estados m_bRodando = False m_bPausada = False m_bTerminar = False m_bLoop = False RETURN True EXCEPTION Error("Erro ao parar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Thread_Pause: Pausa a execução da thread //----------------------------------------------------------------------------- PROCEDURE Thread_Pause() TRY IF m_bRodando AND NOT m_bPausada THEN m_bPausada = True Trace("[Thread:" + m_sUUID + "] Thread pausada") RETURN True END RETURN False EXCEPTION Error("Erro ao pausar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Thread_Resume: Retoma a execução da thread //----------------------------------------------------------------------------- PROCEDURE Thread_Resume() TRY IF m_bRodando AND m_bPausada THEN m_bPausada = False Trace("[Thread:" + m_sUUID + "] Thread retomada") RETURN True END RETURN False EXCEPTION Error("Erro ao retomar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // Thread_Wait: Aguarda o término da thread //----------------------------------------------------------------------------- PROCEDURE Thread_Wait(pTimeoutMS IS INT = 0) TRY LOCAL nInicio IS INT = TimeSys() WHILE m_bRodando Multitask(10) // Verifica timeout se especificado IF pTimeoutMS > 0 AND (TimeSys() - nInicio) > pTimeoutMS THEN RETURN False // Timeout END END RETURN True // Thread terminou EXCEPTION Error("Erro ao aguardar thread: " + ExceptionInfo()) RETURN False END END
//============================================================================= // MÉTODOS PRIVADOS //============================================================================= PRIVATE
//----------------------------------------------------------------------------- // Thread_ExecuteWrapper: Wrapper para execução da thread //----------------------------------------------------------------------------- PROCEDURE Thread_ExecuteWrapper() TRY Trace("[Thread:" + m_sUUID + "] Iniciando execução") IF m_bLoop THEN // Execução em loop WHILE NOT m_bTerminar IF NOT m_bPausada THEN // Executa a procedure via indirection IndirectExecute(m_sProcedureTarget, ieProcedure) END // Pausa entre execuções ThreadPause(m_nIntervaloLoop) END ELSE // Execução única IF NOT m_bTerminar AND NOT m_bPausada THEN IndirectExecute(m_sProcedureTarget, ieProcedure) END END Trace("[Thread:" + m_sUUID + "] Execução finalizada") EXCEPTION Error("[Thread:" + m_sUUID + "] Erro na execução: " + ExceptionInfo()) FINALLY m_bRodando = False END END
//============================================================================= // MÉTODOS DE CONSULTA (GETTERS) //============================================================================= PUBLIC
//----------------------------------------------------------------------------- // IsRunning: Retorna se a thread está rodando //----------------------------------------------------------------------------- PROCEDURE IsRunning() RETURN m_bRodando END
//----------------------------------------------------------------------------- // IsPaused: Retorna se a thread está pausada //----------------------------------------------------------------------------- PROCEDURE IsPaused() RETURN m_bPausada END
//----------------------------------------------------------------------------- // IsLoop: Retorna se a thread está em modo loop //----------------------------------------------------------------------------- PROCEDURE IsLoop() RETURN m_bLoop END
//----------------------------------------------------------------------------- // GetThreadID: Retorna o ID da thread //----------------------------------------------------------------------------- PROCEDURE GetThreadID() RETURN m_sThreadID END
//----------------------------------------------------------------------------- // GetUUID: Retorna o identificador único da instância //----------------------------------------------------------------------------- PROCEDURE GetUUID() RETURN m_sUUID END
//----------------------------------------------------------------------------- // GetExecutionTime: Retorna o tempo de execução em milissegundos //----------------------------------------------------------------------------- PROCEDURE GetExecutionTime() IF m_bRodando AND m_nTempoInicio > 0 THEN RETURN TimeSys() - m_nTempoInicio ELSE RETURN m_nTempoExecucao END END
//----------------------------------------------------------------------------- // GetStatus: Retorna string com status detalhado da thread //----------------------------------------------------------------------------- PROCEDURE GetStatus() LOCAL sStatus IS STRING = "[Thread:" + m_sUUID + "] " IF m_bRodando THEN IF m_bPausada THEN sStatus += "PAUSADA" ELSE sStatus += "RODANDO" END IF m_bLoop THEN sStatus += " (LOOP: " + m_nIntervaloLoop + "ms)" END sStatus += " - Tempo: " + GetExecutionTime() + "ms" ELSE sStatus += "PARADA" IF m_nTempoExecucao > 0 THEN sStatus += " - Último tempo: " + m_nTempoExecucao + "ms" END END RETURN sStatus END
END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em agosto, 29 2025 - 2:14 AM |
//============================================================================= // Classe: clsMultiThread // Finalidade: Gerenciamento coordenado de múltiplas threads // Autor: Baseado na análise do fórum PcSoft // Versão: 1.0 // Data: 28/08/2025 //=============================================================================
CLASS clsMultiThread
//============================================================================= // ATRIBUTOS PRIVADOS //============================================================================= PRIVATE m_arrThreads IS ARRAY OF clsThread // Array de threads gerenciadas m_arrThreadIDs IS ARRAY OF STRING // IDs das threads para controle m_nMaxThreads IS INT = 10 // Número máximo de threads simultâneas m_bRodando IS BOOLEAN = False // Flag do gerenciador ativo m_sUUID IS STRING = "" // Identificador único da instância m_nThreadsAtivas IS INT = 0 // Contador de threads ativas m_nThreadsCriadas IS INT = 0 // Contador total de threads criadas m_bAutoCleanup IS BOOLEAN = True // Limpeza automática de threads finalizadas m_nIntervaloMonitor IS INT = 500 // Intervalo de monitoramento em ms m_oThreadMonitor IS clsThread // Thread de monitoramento interno
//============================================================================= // MÉTODOS PÚBLICOS //============================================================================= PUBLIC
//----------------------------------------------------------------------------- // Constructor: Inicializa o gerenciador de múltiplas threads //----------------------------------------------------------------------------- PROCEDURE Constructor(pMaxThreads IS INT = 10, pAutoCleanup IS BOOLEAN = True) TRY // Inicialização dos atributos m_sUUID = SysUUID() m_nMaxThreads = pMaxThreads m_bAutoCleanup = pAutoCleanup m_bRodando = False m_nThreadsAtivas = 0 m_nThreadsCriadas = 0 m_nIntervaloMonitor = 500 // Inicializa arrays ArrayDeleteAll(m_arrThreads) ArrayDeleteAll(m_arrThreadIDs) // Cria thread de monitoramento m_oThreadMonitor = new clsThread("", threadNormal) Trace("[MultiThread:" + m_sUUID + "] Gerenciador criado - Max threads: " + m_nMaxThreads) EXCEPTION Error("Erro na inicialização do MultiThread: " + ExceptionInfo()) END END
//----------------------------------------------------------------------------- // Destructor: Limpa todos os recursos //----------------------------------------------------------------------------- PROCEDURE Destructor() TRY MultiThread_StopAll() // Destrói thread de monitoramento IF m_oThreadMonitor <> Null THEN delete m_oThreadMonitor END Trace("[MultiThread:" + m_sUUID + "] Gerenciador destruído") EXCEPTION // Log silencioso para evitar erros na destruição END END
//----------------------------------------------------------------------------- // MultiThread_Start: Inicia o gerenciador //----------------------------------------------------------------------------- PROCEDURE MultiThread_Start() TRY IF NOT m_bRodando THEN m_bRodando = True // Inicia monitoramento se auto cleanup estiver ativo IF m_bAutoCleanup THEN m_oThreadMonitor.Thread_StartLoop("MultiThread_MonitorThreads", m_nIntervaloMonitor) END Trace("[MultiThread:" + m_sUUID + "] Gerenciador iniciado") RETURN True END RETURN False EXCEPTION Error("Erro ao iniciar MultiThread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // MultiThread_Stop: Para o gerenciador e todas as threads //----------------------------------------------------------------------------- PROCEDURE MultiThread_StopAll() TRY // Para thread de monitoramento IF m_oThreadMonitor <> Null THEN m_oThreadMonitor.Thread_Stop() END // Para todas as threads gerenciadas LOCAL i IS INT FOR i = 1 TO ArrayCount(m_arrThreads) IF m_arrThreads[i] <> Null THEN m_arrThreads[i].Thread_Stop() delete m_arrThreads[i] END END // Limpa arrays ArrayDeleteAll(m_arrThreads) ArrayDeleteAll(m_arrThreadIDs) // Reset contadores m_nThreadsAtivas = 0 m_bRodando = False Trace("[MultiThread:" + m_sUUID + "] Todas as threads paradas") RETURN True EXCEPTION Error("Erro ao parar MultiThread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // AddThread: Adiciona uma nova thread ao pool //----------------------------------------------------------------------------- PROCEDURE AddThread(pProcedureTarget IS STRING, pPrioridade IS INT = threadNormal, pAutoStart IS BOOLEAN = True) TRY // Verifica limite de threads IF ArrayCount(m_arrThreads) >= m_nMaxThreads THEN Error("Limite máximo de threads atingido: " + m_nMaxThreads) RETURN "" END // Cria nova thread LOCAL oNovaThread IS clsThread = new clsThread(pProcedureTarget, pPrioridade) IF oNovaThread <> Null THEN // Adiciona aos arrays ArrayAdd(m_arrThreads, oNovaThread) ArrayAdd(m_arrThreadIDs, oNovaThread.GetUUID()) m_nThreadsCriadas++ // Inicia automaticamente se solicitado IF pAutoStart THEN oNovaThread.Thread_Start() m_nThreadsAtivas++ END LOCAL sThreadID IS STRING = oNovaThread.GetUUID() Trace("[MultiThread:" + m_sUUID + "] Thread adicionada: " + sThreadID) RETURN sThreadID ELSE Error("Falha ao criar nova thread") RETURN "" END EXCEPTION Error("Erro ao adicionar thread: " + ExceptionInfo()) RETURN "" END END
//----------------------------------------------------------------------------- // AddLoopThread: Adiciona uma thread em modo loop //----------------------------------------------------------------------------- PROCEDURE AddLoopThread(pProcedureTarget IS STRING, pIntervaloMS IS INT = 100, pPrioridade IS INT = threadNormal, pAutoStart IS BOOLEAN = True) TRY // Verifica limite de threads IF ArrayCount(m_arrThreads) >= m_nMaxThreads THEN Error("Limite máximo de threads atingido: " + m_nMaxThreads) RETURN "" END // Cria nova thread LOCAL oNovaThread IS clsThread = new clsThread(pProcedureTarget, pPrioridade) IF oNovaThread <> Null THEN // Adiciona aos arrays ArrayAdd(m_arrThreads, oNovaThread) ArrayAdd(m_arrThreadIDs, oNovaThread.GetUUID()) m_nThreadsCriadas++ // Inicia em modo loop se solicitado IF pAutoStart THEN oNovaThread.Thread_StartLoop(pProcedureTarget, pIntervaloMS, pPrioridade) m_nThreadsAtivas++ END LOCAL sThreadID IS STRING = oNovaThread.GetUUID() Trace("[MultiThread:" + m_sUUID + "] Thread loop adicionada: " + sThreadID + " (Intervalo: " + pIntervaloMS + "ms)") RETURN sThreadID ELSE Error("Falha ao criar nova thread loop") RETURN "" END EXCEPTION Error("Erro ao adicionar thread loop: " + ExceptionInfo()) RETURN "" END END
//----------------------------------------------------------------------------- // RemoveThread: Remove uma thread específica //----------------------------------------------------------------------------- PROCEDURE RemoveThread(pThreadID IS STRING) TRY LOCAL nIndice IS INT = FindThreadIndex(pThreadID) IF nIndice > 0 THEN // Para a thread m_arrThreads[nIndice].Thread_Stop() // Remove da memória delete m_arrThreads[nIndice] // Remove dos arrays ArrayDelete(m_arrThreads, nIndice) ArrayDelete(m_arrThreadIDs, nIndice) // Atualiza contador IF m_nThreadsAtivas > 0 THEN m_nThreadsAtivas-- END Trace("[MultiThread:" + m_sUUID + "] Thread removida: " + pThreadID) RETURN True ELSE Error("Thread não encontrada: " + pThreadID) RETURN False END EXCEPTION Error("Erro ao remover thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // StartThread: Inicia uma thread específica //----------------------------------------------------------------------------- PROCEDURE StartThread(pThreadID IS STRING) TRY LOCAL nIndice IS INT = FindThreadIndex(pThreadID) IF nIndice > 0 THEN IF m_arrThreads[nIndice].Thread_Start() THEN m_nThreadsAtivas++ Trace("[MultiThread:" + m_sUUID + "] Thread iniciada: " + pThreadID) RETURN True END ELSE Error("Thread não encontrada: " + pThreadID) END RETURN False EXCEPTION Error("Erro ao iniciar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // StopThread: Para uma thread específica //----------------------------------------------------------------------------- PROCEDURE StopThread(pThreadID IS STRING) TRY LOCAL nIndice IS INT = FindThreadIndex(pThreadID) IF nIndice > 0 THEN IF m_arrThreads[nIndice].Thread_Stop() THEN IF m_nThreadsAtivas > 0 THEN m_nThreadsAtivas-- END Trace("[MultiThread:" + m_sUUID + "] Thread parada: " + pThreadID) RETURN True END ELSE Error("Thread não encontrada: " + pThreadID) END RETURN False EXCEPTION Error("Erro ao parar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // PauseThread: Pausa uma thread específica //----------------------------------------------------------------------------- PROCEDURE PauseThread(pThreadID IS STRING) TRY LOCAL nIndice IS INT = FindThreadIndex(pThreadID) IF nIndice > 0 THEN RETURN m_arrThreads[nIndice].Thread_Pause() ELSE Error("Thread não encontrada: " + pThreadID) RETURN False END EXCEPTION Error("Erro ao pausar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // ResumeThread: Retoma uma thread específica //----------------------------------------------------------------------------- PROCEDURE ResumeThread(pThreadID IS STRING) TRY LOCAL nIndice IS INT = FindThreadIndex(pThreadID) IF nIndice > 0 THEN RETURN m_arrThreads[nIndice].Thread_Resume() ELSE Error("Thread não encontrada: " + pThreadID) RETURN False END EXCEPTION Error("Erro ao retomar thread: " + ExceptionInfo()) RETURN False END END
//----------------------------------------------------------------------------- // WaitAllThreads: Aguarda o término de todas as threads //----------------------------------------------------------------------------- PROCEDURE WaitAllThreads(pTimeoutMS IS INT = 0) TRY LOCAL nInicio IS INT = TimeSys() LOCAL i IS INT WHILE m_nThreadsAtivas > 0 // Verifica cada thread FOR i = 1 TO ArrayCount(m_arrThreads) IF m_arrThreads[i] <> Null THEN IF NOT m_arrThreads[i].IsRunning() THEN // Thread terminou, atualiza contador IF m_nThreadsAtivas > 0 THEN m_nThreadsAtivas-- END END END END Multitask(50) // Verifica timeout se especificado IF pTimeoutMS > 0 AND (TimeSys() - nInicio) > pTimeoutMS THEN RETURN False // Timeout END END RETURN True // Todas as threads terminaram EXCEPTION Error("Erro ao aguardar threads: " + ExceptionInfo()) RETURN False END END
//============================================================================= // MÉTODOS PRIVADOS //============================================================================= PRIVATE
//----------------------------------------------------------------------------- // FindThreadIndex: Encontra o índice de uma thread pelo ID //----------------------------------------------------------------------------- PROCEDURE FindThreadIndex(pThreadID IS STRING) LOCAL i IS INT FOR i = 1 TO ArrayCount(m_arrThreadIDs) IF m_arrThreadIDs[i] = pThreadID THEN RETURN i END END RETURN 0 // Não encontrado END
//----------------------------------------------------------------------------- // MultiThread_MonitorThreads: Monitora e limpa threads finalizadas //----------------------------------------------------------------------------- PROCEDURE MultiThread_MonitorThreads() TRY LOCAL i IS INT LOCAL nThreadsRemovidas IS INT = 0 // Verifica threads finalizadas para limpeza FOR i = ArrayCount(m_arrThreads) TO 1 STEP -1 IF m_arrThreads[i] <> Null THEN IF NOT m_arrThreads[i].IsRunning() THEN // Thread finalizada, remove se auto cleanup estiver ativo IF m_bAutoCleanup THEN LOCAL sThreadID IS STRING = m_arrThreads[i].GetUUID() delete m_arrThreads[i] ArrayDelete(m_arrThreads, i) ArrayDelete(m_arrThreadIDs, i) nThreadsRemovidas++ IF m_nThreadsAtivas > 0 THEN m_nThreadsAtivas-- END END END END END IF nThreadsRemovidas > 0 THEN Trace("[MultiThread:" + m_sUUID + "] Limpeza automática: " + nThreadsRemovidas + " threads removidas") END EXCEPTION Error("[MultiThread:" + m_sUUID + "] Erro no monitoramento: " + ExceptionInfo()) END END
//============================================================================= // MÉTODOS DE CONSULTA (GETTERS) //============================================================================= PUBLIC
//----------------------------------------------------------------------------- // GetActiveThreadsCount: Retorna o número de threads ativas //----------------------------------------------------------------------------- PROCEDURE GetActiveThreadsCount() RETURN m_nThreadsAtivas END
//----------------------------------------------------------------------------- // GetTotalThreadsCount: Retorna o número total de threads gerenciadas //----------------------------------------------------------------------------- PROCEDURE GetTotalThreadsCount() RETURN ArrayCount(m_arrThreads) END
//----------------------------------------------------------------------------- // GetCreatedThreadsCount: Retorna o número total de threads criadas //----------------------------------------------------------------------------- PROCEDURE GetCreatedThreadsCount() RETURN m_nThreadsCriadas END
//----------------------------------------------------------------------------- // GetMaxThreads: Retorna o limite máximo de threads //----------------------------------------------------------------------------- PROCEDURE GetMaxThreads() RETURN m_nMaxThreads END
//----------------------------------------------------------------------------- // IsRunning: Retorna se o gerenciador está ativo //----------------------------------------------------------------------------- PROCEDURE IsRunning() RETURN m_bRodando END
//----------------------------------------------------------------------------- // GetUUID: Retorna o identificador único da instância //----------------------------------------------------------------------------- PROCEDURE GetUUID() RETURN m_sUUID END
//----------------------------------------------------------------------------- // GetThreadIDs: Retorna array com IDs de todas as threads //----------------------------------------------------------------------------- PROCEDURE GetThreadIDs() RETURN m_arrThreadIDs END
//----------------------------------------------------------------------------- // GetThreadStatus: Retorna status de uma thread específica //----------------------------------------------------------------------------- PROCEDURE GetThreadStatus(pThreadID IS STRING) LOCAL nIndice IS INT = FindThreadIndex(pThreadID) IF nIndice > 0 THEN RETURN m_arrThreads[nIndice].GetStatus() ELSE RETURN "Thread não encontrada: " + pThreadID END END
//----------------------------------------------------------------------------- // GetStatus: Retorna string com status detalhado do gerenciador //----------------------------------------------------------------------------- PROCEDURE GetStatus() LOCAL sStatus IS STRING = "[MultiThread:" + m_sUUID + "] " sStatus += "Ativas: " + m_nThreadsAtivas + "/" + ArrayCount(m_arrThreads) sStatus += " | Criadas: " + m_nThreadsCriadas sStatus += " | Max: " + m_nMaxThreads IF m_bRodando THEN sStatus += " | Status: RODANDO" ELSE sStatus += " | Status: PARADO" END IF m_bAutoCleanup THEN sStatus += " | AutoCleanup: ON" ELSE sStatus += " | AutoCleanup: OFF" END RETURN sStatus END
END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
| | |
| |
|
|
|