Ajuda com Thread
Olá pessoal, preciso de uma ajuda, montei um projeto que integra com a catraca Fit da TopData, até aí tudo bem, através dos exemplos consegui fazer a integração, comunicar com a catraca a através do clique no botão liberar a mesma, e é aqui que estou tendo problemas, quando a catraca está conectada ela fica num loop o tempo todo da procedure abaixo, procedure esta que está em uma unit declarada no meu projeto e fica verificando conexão, ping, etc. Quando clico com mouse no botão para liberar a catraca ok, faz a liberação, acontece que tenho que liberar através do enter dado pelo leitor de cartão magnético, o associado passa o cartão e o código dele vem para o edit e depois da o enter, o botão está como default para receber o enter, o problema é que enquanto a catraca está conectada e fazendo o loop, não deixa passar para o enter dado através do leitor. Andei dando uma estudada sobre Thread mas estou meio perdido, talvez alguém tenha outra solução que possa me ajudar. Segue abaixo o código para exemplificar melhor. Talvez a solução seria declarar a procedure MaquinaEstados dentro de uma Thread, mas realmente estou perdido sobre como fazer.
procedure TEasyInnerControllerOnline.MaquinaEstados;
var
index: integer;
InnerAtual: TInner;
begin
// Enquanto a variável de controle da maquina de ESTADOs estiver false..
while (not Parar) do
begin
for index := 0 to ListaInners.Count - 1 do
Begin
InnerAtual := ListaInners.Items[index];
// Realiza Um Switch do ESTADO Atual do Inner..
CASE InnerAtual.EstadoAtual OF
aqui fica fazendo a verificações
end;
Sleep(1);
end;
end;
// Fecha a porta de Comunicação quando sai da maquina de estados..
FecharPortaComunicacao();
end;
E preciso passar para código abaixo para liberar catraca, porém fica parado na rotina acima.
if ibqAssociadoSTATUS.Value = 'ATIVO' then
begin
btnEntrada.OnClick(Self);
end;
Obrigado.
procedure TEasyInnerControllerOnline.MaquinaEstados;
var
index: integer;
InnerAtual: TInner;
begin
// Enquanto a variável de controle da maquina de ESTADOs estiver false..
while (not Parar) do
begin
for index := 0 to ListaInners.Count - 1 do
Begin
InnerAtual := ListaInners.Items[index];
// Realiza Um Switch do ESTADO Atual do Inner..
CASE InnerAtual.EstadoAtual OF
aqui fica fazendo a verificações
end;
Sleep(1);
end;
end;
// Fecha a porta de Comunicação quando sai da maquina de estados..
FecharPortaComunicacao();
end;
E preciso passar para código abaixo para liberar catraca, porém fica parado na rotina acima.
if ibqAssociadoSTATUS.Value = 'ATIVO' then
begin
btnEntrada.OnClick(Self);
end;
Obrigado.
Marcelo Vieira
Curtidas 0
Respostas
Emerson Nascimento
14/02/2020
eu não entendi muito bem o processo, mas se você não quer que seu loop "trave" a entrada de dados, faça uma chamada a Application.ProcessMessages dentro do loop. isto faz com que o programa permita interações de fora do loop.
Se ainda assim não resolver o teu problema, é possível, sim (e fácil), passar ao uso de threads.
procedure TEasyInnerControllerOnline.MaquinaEstados;
var
index: integer;
InnerAtual: TInner;
begin
// Enquanto a variável de controle da maquina de ESTADOs estiver false..
while (not Parar) do
begin
Application.ProcessMessages;
for index := 0 to ListaInners.Count - 1 do
begin
InnerAtual := ListaInners.Items[index];
// Realiza Um Switch do ESTADO Atual do Inner..
CASE InnerAtual.EstadoAtual OF
aqui fica fazendo a verificações
end;
sleep(1);
end;
end;
// Fecha a porta de Comunicação quando sai da maquina de estados..
FecharPortaComunicacao();
end;Se ainda assim não resolver o teu problema, é possível, sim (e fácil), passar ao uso de threads.
GOSTEI 0
Marcelo Vieira
14/02/2020
eu não entendi muito bem o processo, mas se você não quer que seu loop "trave" a entrada de dados, faça uma chamada a Application.ProcessMessages dentro do loop. isto faz com que o programa permita interações de fora do loop.
Se ainda assim não resolver o teu problema, é possível, sim (e fácil), passar ao uso de threads.
procedure TEasyInnerControllerOnline.MaquinaEstados;
var
index: integer;
InnerAtual: TInner;
begin
// Enquanto a variável de controle da maquina de ESTADOs estiver false..
while (not Parar) do
begin
Application.ProcessMessages;
for index := 0 to ListaInners.Count - 1 do
begin
InnerAtual := ListaInners.Items[index];
// Realiza Um Switch do ESTADO Atual do Inner..
CASE InnerAtual.EstadoAtual OF
aqui fica fazendo a verificações
end;
sleep(1);
end;
end;
// Fecha a porta de Comunicação quando sai da maquina de estados..
FecharPortaComunicacao();
end;Se ainda assim não resolver o teu problema, é possível, sim (e fácil), passar ao uso de threads.
Primeiramente obrigado pela dica Emerson, o Application.ProcessMessages a princípio resolveu nos testes que fiz, mas ainda gera um delay de processamento, vou colocar em produção no micro que está a catraca. De qualquer forma está recebendo o enter através do teclado pelo botão que está como default, o que antes não acontecia.
GOSTEI 0
Emerson Nascimento
14/02/2020
você pode colocar o Application.ProcessMessages dentro do for também.
procedure TEasyInnerControllerOnline.MaquinaEstados;
var
index: integer;
InnerAtual: TInner;
begin
// Enquanto a variável de controle da maquina de ESTADOs estiver false..
while (not Parar) do
begin
Application.ProcessMessages; // coloquei aqui
for index := 0 to ListaInners.Count - 1 do
begin
Application.ProcessMessages; // e aqui também
InnerAtual := ListaInners.Items[index];
// Realiza Um Switch do ESTADO Atual do Inner..
CASE InnerAtual.EstadoAtual OF
aqui fica fazendo a verificações
end;
sleep(1);
end;
end;
// Fecha a porta de Comunicação quando sai da maquina de estados..
FecharPortaComunicacao();
end;GOSTEI 0
Marcelo Vieira
14/02/2020
você pode colocar o Application.ProcessMessages dentro do for também.
procedure TEasyInnerControllerOnline.MaquinaEstados;
var
index: integer;
InnerAtual: TInner;
begin
// Enquanto a variável de controle da maquina de ESTADOs estiver false..
while (not Parar) do
begin
Application.ProcessMessages; // coloquei aqui
for index := 0 to ListaInners.Count - 1 do
begin
Application.ProcessMessages; // e aqui também
InnerAtual := ListaInners.Items[index];
// Realiza Um Switch do ESTADO Atual do Inner..
CASE InnerAtual.EstadoAtual OF
aqui fica fazendo a verificações
end;
sleep(1);
end;
end;
// Fecha a porta de Comunicação quando sai da maquina de estados..
FecharPortaComunicacao();
end;Olá Emerson, obrigado pelo apoio, ainda continua com um delay mas acredito que não vai prejudicar o processo, é muito rápido. Vou colocar em produção e acompanhar. Valeu.
GOSTEI 0
Emerson Nascimento
14/02/2020
Certo.
Mas se não ficar satisfatório, o uso de thread deve ser avaliado. Não é difícil implementar.
Mas se não ficar satisfatório, o uso de thread deve ser avaliado. Não é difícil implementar.
GOSTEI 0