Ajuda com Thread

14/02/2020

7

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.
Responder

Posts

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.
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.
Responder

15/02/2020

Marcelo Vieira

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.
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.
Responder
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;
Responder

17/02/2020

Marcelo Vieira

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.
Responder
Certo.

Mas se não ficar satisfatório, o uso de thread deve ser avaliado. Não é difícil implementar.
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários. Para saber mais sobre o uso de cookies,
consulte nossa política de privacidade. Ao continuar navegando em nosso site, você concorda com a nossa política.

Aceitar