Fórum Thread - Funciona mas tbém Trava o sistema. #51163

31/05/2005

0

Olá!
Sou Desenv. D7 + IB/FB + DBExpress. :D

Pela primeira vez estou fazendo uma Thread, então
calma ai, pois já pesquisei muito(Livros/Net), mas algumas coisas
ainda não consegui entender. :shock:



Tenho o seguinte problema: :oops: :?:

Tenho um (SQL_Produtos)+(dst_produtos)+(Cds_produtos)+(Ds_produtos)

Cds_FetchOnDemaind:= True
PacketRecords := 100

Este form é usado para inclusão e navegação, está funcionando
normalmente, o problema é a Thread.

Neste ao iniciar, carrego todos os produtos p/ navegar do 1º ao último,
com o auxílio de uma Thread que está funcionando muito bem.

Mas antes que todos os registros são carregados no CDS, ás vezes tenho
que interromper a Thread, e clicar no BOTÃO INCLUI e ai tudo trava.


Perguntas:
==========
1- Então o que estou fazendo de errado para que isso estar acontecendo?

2- Porque não consigo executar um PT.RESUME no meu DATA MÓDULO, após um
After cancel /ou AfterApplyUpdade ?
Não consigo acessar PT em tempo de compilação.

3- Como saber se uma Thread já terminou ?


Desde já meus agradecimentos a quem puder ajudar.

T+

ANT.CARLOS/SP


:arrow:
Extrututa principal do Form
---------------------------
unit Form_Cadprod;

interface

uses
Windows, ...

type
TFrm_Cadprod = class(TFrmFichaPai)
Ed_codprod: TDBEdit, ...;



private
{ Private declarations }

PT: Thread_Cadprod;
===================
end;

var
Frm_Cadprod: TFrm_Cadprod;


Atualizacões ao Criar o form
----------------------------------
- Crio uma Query p/ pegar qtde de PRodutos e carrego a var Cds_prod_qtde.
- DMPROD.Cds_Produtos.FetchOnDemand := false;


//...O que está de errado em testar se a Thread está ativa ?
procedure TDMPROD.Cds_ProdutosAfterCancel(DataSet: TDataSet);
begin
IF (DMPROD.Cds_Produtos.RecordCount < Cds_prod_qtde) and (Not Assigned(Thread_Cadprod)) then Then
PT.Resume;

Erro: Variable requerid - Undeclared Identifier PT :?:
====
end;


procedure TFrm_Cadprod.FormDestroy(Sender: TObject);
begin
PT.terminate;
PT.free;
end;



Estrututa da Thread:
-----------------------------------
procedure Thread_Cadprod.Execute;
begin
Repeat
//...Aqui, verifico se o Cds estiver em modo de Insersão/Edit,
desejaria para a Thread temporariamente.
IF DMPRODCds_Produtos.state IN [DsInsert,DsEdit] Then Begin
Suspend;
End;


//...Aqui carrego o Cds, a var Cds_prod_qtde foi carregado ao
criar o form Frm_Produtos.
DMPROD.Cds_Produtos.GetNextPacket;
IF DMPROD.Cds_Produtos.RecordCount = Cds_prod_qtde Then Begin
DMPROD.Cds_Produtos.FetchOnDemand := True;
Terminate;
End;
Until Terminated;
end;

Obs: se não houver uma intervensão através de um evento de Inclusão ou Edit,
==== tudo funciona bem.
-----------------------------------


Ant.carlos/sp

Ant.carlos/sp

Responder

Posts

01/06/2005

Beppe

Oi!

1) Parece ser falta de sincronização.
2) PT é private do form!! Torne public
3) if T.Terminated then... (vc já fazia isto)

Como vc interrompe a thread? Suspend ou Terminate?

Acredito que se vc mover o código principal do loop do seu novo thread para uma novo método, e chamá-lo através de Synchronize, o problema se resolve.

procedure Thread_Cadprod.Carrega;
begin
 IF DMPRODCds_Produtos.state IN [DsInsert,DsEdit] Then Begin
Suspend;
End;


//...Aqui carrego o Cds, a var Cds_prod_qtde foi carregado ao
criar o form Frm_Produtos.
DMPROD.Cds_Produtos.GetNextPacket;
IF DMPROD.Cds_Produtos.RecordCount = Cds_prod_qtde Then Begin
DMPROD.Cds_Produtos.FetchOnDemand := True;
Terminate;
End;
end;

procedure Thread_Cadprod.Execute;
begin
  repeat
    Synchronize(Carrega);
  until Terminated;
end;


O problema é que o thread ainda pode estar na sua seção crítica na chamada ao ´Incluir´.


Responder

Gostei + 0

05/06/2005

Ant.carlos/sp

Depois de muito teste, descobri que a Thread é + rápida que a atualização do componente Cds_produtos.
Pois qdo clico no botão incluir, um append é executado e a thread interrompida, mas isto não acontece, porque a thread é tão rápida que o estado do Cds_protudos ainda permanece por + algumas volta no loop em estado de Browse antes de ser atualizado e por isso estava travando.



ALTERAÇÃO QUE FUNCIONOU
Estrututa da Thread:
-----------------------------------
procedure Thread_Cadprod.Execute;
begin
Repeat
IF DMPRODCds_Produtos.state IN [DSBROSE] Then Begin
//...Aqui carrego o Cds, a var Cds_prod_qtde foi carregado ao
criar o form Frm_Produtos.
DMPROD.Cds_Produtos.GetNextPacket;
IF DMPROD.Cds_Produtos.RecordCount = Cds_prod_qtde Then
Begin
DMPROD.Cds_Produtos.FetchOnDemand := True;
Terminate;
End;
Until Terminated;
end;


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar