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.
-----------------------------------
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
Curtir tópico
+ 0
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.
O problema é que o thread ainda pode estar na sua seção crítica na chamada ao ´Incluir´.
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;
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
Clique aqui para fazer login e interagir na Comunidade :)