Ir para conteúdo
Fórum Script Brasil
  • 0

Demora em processo muito grande


robinhocne

Pergunta

enho um aplicativo para consultar as vendas de uma banco postgre, jogo os registros na query e faço um loop pegando os produtos e pagamentos de cada venda e montando um JSON, após montado o JSON realizo um post em um webservice de outro software de terceiro(erp principal), tudo isso coloquei dentro do processo de uma thread, consultando pelo log a cada 4 há 6 segundos monta o json e faz o post no webservice, a situção é que em 1 mes de venda de apenas um loja tenho em media 25.000 vendas isso está dando mais de 24 horas executando.
Com isso comecei a caçado sobre pool de thread, parallel e tasks, na verdade não sei o que usar e qual maneira corretamente, já vi vários videos, li artigos, mas não consegui materializar tudo em linha de codigo com meu problema, na verdade estava pretendendo enviar 100 posts no webservice, pois vários ao mesmo tempo a api consegue processar rapidamente, então o que preciso é de uma ajuda se realizo com pool de tread, parallel ou task...
Para terem uma noção melhor montei um exemplo que chega bem proximo do modelo funcional do processo, como existe varias consultas e validação, creio que não compensa postar o codigo....

 

unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
MinhaThread = class(TThread)
procedure Execute; override;
procedure Verifica;
procedure Fechar;
Private
constructor Create();
end;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
thread: MinhaThread;
public
{ Public declarations }
procedure consultaProcesso(Sender: TObject);
procedure postJSON(JSON:String);
end;
var
Form1: TForm1;
I : Integer;
JSON:String;
implementation
{$R *.dfm}
{ MinhaThread }
constructor MinhaThread.Create;
begin
inherited
Create(True);
FreeOnTerminate := True;
Priority := tpLower;
Resume;
end;
procedure MinhaThread.Execute;
Var Sender : TObject;
begin
Synchronize(Verifica);
Form1.consultaProcesso(Sender); // Executar Rotina ( Procedures )
while not Terminated do
begin
Sleep (10);
Terminate; // Finaliza a Thread
Synchronize(Fechar);
end;
end;
procedure MinhaThread.Fechar;
begin
//application.terminate;
end;
procedure MinhaThread.Verifica;
begin
Form1.Caption := 'EXECUTANDO...'+IntToStr(I);
end;
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
thread := MinhaThread.Create();
end;
procedure TForm1.consultaProcesso(Sender: TObject);
begin
//exemplo com o for
// porem aqui eu percorro a query, passo 
// para a variavel JSON o json que está na query
// e chamo o metodo post
for I := 0 to 100 do
begin
postJSON(JSON);
end;
end;
procedure TForm1.postJSON(JSON: String);
begin
//faz um post pelo idHTTP;
Memo1.Lines.Add(DateTimeToStr(now)+ ' - Executando JSON '+IntToStr(I));
//para simular um tempo de espera do retorno
Sleep(1000);
//retorno...
Memo1.Lines.Add(DateTimeToStr(now)+ ' - Retorno JSON '+IntToStr(I));
end;
end.

 

Link para o comentário
Compartilhar em outros sites

14 respostass a esta questão

Posts Recomendados

  • 0

se voce não sabe, voce pode executar varias threads ao mesmo tempo

exemplo

{ Private declarations }

    thread0: MinhaThread;
    thread1: MinhaThread;
    thread2: MinhaThread;
    thread3: MinhaThread;
    thread4: MinhaThread;
    thread5: MinhaThread;
    thread6: MinhaThread;
    thread7: MinhaThread;
    thread8: MinhaThread;
    thread9: MinhaThread;

etc....

    thread100: MinhaThread;

com isso voce pode dividir o trabalho, aumentando a velocidade de processamento.

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

hum.;... não teria como criar Array de Threads ? mas mesmo assm é uma boa solução... o que estou tendo problema é que quando chamo o post pelo idHttp ele leva um tempo para ter a resposta, nesse caso teria que jogar 100 de uma vez sem aguardar a resposta, mas esperar que vá liberando as 100 para ir entrando mais....isso que estou pedindo e não sabendo como montar.

Link para o comentário
Compartilhar em outros sites

  • 0

não teria como criar Array de Threads ?

voce pode criar um array ou multithreads

https://stackoverflow.com/questions/23936905/how-to-wait-for-multiple-threads-to-terminate-in-delphi

nesses links vai encontrar alguns exemplos de uso

https://www.google.com.br/?gws_rd=ssl#q=array+de+threads+delphi

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Bom dia, Jhonas já vi vários exemplos mas não consegui adaptar esse conceito....

Eu fiz dessa maneira...

procedure TfrmPSyncBack.Button2Click(Sender: TObject);
var linha: TStringList;
    a, nrAcu, total, ts :integer;
    aux : Currency;
    lista : TStringList;
    NomeDoLog, texto: string;
    Arquivo: TextFile;
    HTTP: TIdHTTP;
    RequestBody: TStream;
    ResponseBody, retorno, nrCoo, idCaixa, cdEmp, JSON: string;
    qryTeste: TFDQuery;
begin

      linha := TStringList.Create;
      lista := TStringList.Create;

 //gerei um arquivo(txt) com a extensão json para carregar e executar no loop;
 //o arquivo contem o numero do cupom, id caixa, empresa e o json separados por |
 //esses parametros uso para gravar junto com o retorno.

 NomeDoLog := ExtractFilePath(Application.ExeName) + 'log\jsonPSyncBack_20062017_1933.json';
 AssignFile(Arquivo, NomeDoLog);
 {$I-}
 Reset(Arquivo);
 {$I+}

 lista.LoadFromFile(ExtractFilePath(Application.ExeName) + 'log\jsonPSyncBack_20062017_1933.json');

 while (not eof(Arquivo)) do
    begin
                    readln(Arquivo, texto);
                     linha.Delimiter := '|';
                     linha.StrictDelimiter := true;
                     linha.DelimitedText := texto;
                     nrCoo := linha[0];
                     idCaixa := linha[1];
                     cdEmp := linha[2];
                     JSON := linha[3];

                     MyThread := TThread.CreateAnonymousThread(procedure begin

                          qryTeste := nil;
                          qryTeste := TFDQuery.Create(qryTeste);
                          qryTeste.Connection := DtmPSyncBack.conPlatinum;

                                  HTTP := TIdHTTP.Create;
                                  try
                                    try

                                     RequestBody := TStringStream.Create(JSON,TEncoding.UTF8);
                                      try
                                        HTTP.Request.Accept := 'application/json';
                                        HTTP.Request.ContentType := 'application/json;charset=utf-8;';
                                        HTTP.Request.BasicAuthentication := true;
                                        HTTP.Request.Connection  := 'keep-alive';

                                        ResponseBody := UTF8ToString(HTTP.Post('http://user:password@host:port/api/teste/pedido/inclui',RequestBody));

                                        qryTeste.Close;
                                        qryTeste.SQL.Text := 'insert into tbl_adm_logintegracao (cd_empresa,nr_coo,nr_idcaixa,tp_log,ds_log,ds_json,ds_pedidov,dt_cadastro)'+
                                                            ' values ('+#39 +cdEmp+#39+','+#39 +nrCoo+#39+','+#39 +idCaixa+#39+','+#39 +'OK'+#39+','+#39 +'OK'+#39+','+
                                                            #39 +JSON+#39+','+#39 +ResponseBody+#39+',CURRENT_TIMESTAMP)';
                                        qryTeste.ExecSQL;

                                      finally
                                        RequestBody.Free;
                                      end;
                                    except
                                      on E: EIdHTTPProtocolException do
                                      begin

                                        qryTeste.Close;

                                        qryTeste.SQL.Text := 'insert into tbl_adm_logintegracao (cd_empresa,nr_coo,nr_idcaixa,tp_log,ds_log,ds_json,dt_cadastro)'+
                                                            ' values ('+#39 +cdEmp+#39+','+#39 +nrCoo+#39+','+#39 +idCaixa+#39+','+#39 +'ERRO'+#39+','+#39+E.ErrorMessage+#39+','+
                                                            #39 +JSON+#39+',CURRENT_TIMESTAMP)';
                                        qryTeste.ExecSQL;

                                      end;
                                      on E: Exception do
                                      begin
                                      end;
                                    end;
                                  finally
                                    HTTP.Free;
                                  end;


                     end);
          end;

         CloseFile(Arquivo);
         linha := nil;

end;

dados do arquivo .json

4|83653|22|[{"cod_pedidov":"4.83653.22","vitrine":4,"data_emissao":"2017-04-06","data_entrega":"2017-04-06","total":46.97,"quantidade":3,"n_serie":"BE091110100011237675","modelo":"ECF","numecf":22,"nota":83653,"serie":"1","faturar":"I","produtos":[{"item":1,"quantidade":1,"preço":19.99},{"item":2,"quantidade":1,"preço":13.99},{"barra":"2251202415835","item":3,"quantidade":1,"preço":12.99}],"lancamentos":[{"data_vencimento":"2017-04-06","valor_inicial":46.97,"numparc":11,"desc_tipo":"NALIN CREDITO","desc_bandeira":"NALIN","autorizacao":"400786","nsu":"000000444918"}],"dados_cliente":[{"nome":"CONSUMIDOR FINAL","vitrine":4,"endereco":[{"cep":"25225660","numero":""}]}]}]
4|180549|20|[{"cod_pedidov":"4.180549.20","vitrine":4,"data_emissao":"2017-04-10","data_entrega":"2017-04-10","total":68.93,"quantidade":7,"n_serie":"BE091110100011237014","modelo":"ECF","numecf":20,"nota":180549,"serie":"1","faturar":"I","produtos":[{"item":1,"quantidade":1,"preço":29.99},{"barra":"2251204175348","item":2,"quantidade":1,"preço":2.99},{"barra":"2251204175348","item":3,"quantidade":1,"preço":2.99},{"barra":"2251204175348","item":4,"quantidade":1,"preço":2.99},{"barra":"2251203876925","item":5,"quantidade":1,"preço":9.99},{"barra":"2251203876925","item":6,"quantidade":1,"preço":9.99},{"barra":"2251203876925","item":7,"quantidade":1,"preço":9.99}],"lancamentos":[{"data_vencimento":"2017-04-10","valor_inicial":68.93,"numparc":0,"desc_tipo":"DINHEIRO"}],"dados_cliente":[{"nome":"CONSUMIDOR FINAL","vitrine":4,"endereco":[{"cep":"25225660","numero":""}]}]}]
4|179469|20|[{"cod_pedidov":"4.179469.20","vitrine":4,"data_emissao":"2017-04-01","data_entrega":"2017-04-01","total":19.99,"quantidade":1,"n_serie":"BE091110100011237014","modelo":"ECF","numecf":20,"nota":179469,"serie":"1","faturar":"I","produtos":[{"barra":"2251203757378","item":1,"quantidade":1,"preço":19.99}],"lancamentos":[{"data_vencimento":"2017-04-01","valor_inicial":19.99,"numparc":0,"desc_tipo":"DINHEIRO"}],"dados_cliente":[{"nome":"CONSUMIDOR FINAL","vitrine":4,"endereco":[{"cep":"25225660","numero":""}]}]}]
4|84197|22|[{"cod_pedidov":"4.84197.22","vitrine":4,"data_emissao":"2017-04-10","data_entrega":"2017-04-10","total":201.51,"quantidade":9,"n_serie":"BE091110100011237675","modelo":"ECF","numecf":22,"nota":84197,"serie":"1","faturar":"I","produtos":[{"item":1,"quantidade":1,"preço":9.83444},{"item":2,"quantidade":1,"preço":9.83444},{"barra":"2251204456515","item":3,"quantidade":1,"preço":13.83444},{"item":4,"quantidade":1,"preço":38.83444},{"item":5,"quantidade":1,"preço":13.83444},{"barra":"2251204708102","item":6,"quantidade":1,"preço":28.83444},{"item":7,"quantidade":1,"preço":18.83444},{"item":8,"quantidade":1,"preço":38.83444},{"item":9,"quantidade":1,"preço":28.83444}],"lancamentos":[{"data_vencimento":"2017-04-10","valor_inicial":201.51,"numparc":1,"desc_tipo":"NALIN CREDITO","desc_bandeira":"NALIN","autorizacao":"400030","nsu":"000000449536"}],"dados_cliente":[{"nome":"CONSUMIDOR FINAL","vitrine":4,"endereco":[{"cep":"25225660","numero":""}]}]}]

 

fazendo dessa forma acima....o processado fica 100% e aparentemente não está executando, porque não tenho retorno dos inserts....dos retornos do post, depois de uns 10 minutos eu tenho erro de Runtime error 214 at 01B001E.

Creio que teria que fazer assim..... gerar 10 Threads com o post dentro....aguardar o retorno das 10, pois teoricamente as 10 está rodando ao mesmo tempo, então seria mais rapido que rodando 1 por vez e aguardando o retorno.... depois assim que retornar 1 já entra na fila outra....

 

 

 

Screenshot_9.png

Screenshot_10.png

Link para o comentário
Compartilhar em outros sites

  • 0

com relação ao erro

Runtime error 214 at 01B001E.

204 Operação de ponteiro inválida
    Você obterá isso em vários casos:

Se você chamar Dispose ou Freemem com um ponteiro inválido
Caso seja chamado New ou GetMem e não há mais memória disponível. 
O comportamento neste caso depende da configuração de ReturnNilIfGrowHeapFails. 
Se é Verdadeiro, então Nil é retornado. Se False, então o run error 204 
é gerado.

o exemplo abaixo, mostra como evitar esse erro:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type
        TForm1 = class(TForm)
        CheckBox1: TCheckBox;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        private
        { Private declarations }
        public
        { Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function MinhaThread(P:Pointer):LongInt;
var
F :TextFile;
I :Integer;
begin
        {Simula um processo Longo... }
        {Pode ser trocado por qualquer outra rotina que demore muito}
        AssignFile(F, 'C:TESTE.TXT');
        ReWrite(F);

        While not Form1.CheckBox1.Checked do
        begin
                i := i + 1;
                Writeln(F,'Numero: ' + Inttostr(i));
                Sleep(100);
        end;

        CloseFile(F);
end;

{Rotina do Botão}
procedure TForm1.Button1Click(Sender: TObject);
var
hThreadID :THandle;
ThreadID :DWord;
begin
        {Cria a Thread, onde @MinhaThread é o Ponteiro da Função criada}
        hThreadID := CreateThread(nil, 0, @MinhaThread, nil, 0, ThreadID);
end;

end.

Voce tem levar algumas coisas em consideração:

Priority := tpLower;  /// a prioridade de execução  é baixa, nesse caso outros processos rodando no windows terão prioridade acima da thread .... voce pode mudar a prioridade para executar acima de outros processos, inclusive do proprio programa que esta executando a thread quando ela é executada.

no exemplo do outro tópico sobre o uso de thread

procedure MinhaThread.Execute;
Var Sender : TObject;
begin
   synchronize(Verifica); // Acessar a VCL sem travar o programa
   Form1.RotinaX(Sender); // Executar Rotina ( Procedures )

   while not Terminated do
    begin
        Sleep (100);
        Terminate; // Finaliza a Thread
        Form1.Memo1.Lines.Append('Thread Finalizada');
        synchronize(Fechar); // Fechar o programa
    end;

end;

se voce executar 10 threads usando a mesma procedure, elas vão entrar em uma fila ( usando a mesma procedure MinhaThread.Execute) , até que todas sejam terminadas para finalizar.

isso vai demandar um tempo ... se esse tempo for maior que o processo de outra rotina no programa, voce não vai ter os retornos que precisa para continuar a execução de uma outra procedure ou função dentro do programa.

abraço

 

 

 

Link para o comentário
Compartilhar em outros sites

  • 0

Jhonas não consegui adaptar a minha realidade....

function TfrmPSyncBack.MinhaThreadSync(P: Pointer): LongInt;
var linha: TStringList;
    a, nrAcu, total, ts :integer;
    aux : Currency;
    lista : TStringList;
    NomeDoLog, texto: string;
    Arquivo: TextFile;
    HTTP: TIdHTTP;
    RequestBody: TStream;
    ResponseBody, retorno, nrCoo, idCaixa, cdEmp, JSON: string;
    qryTeste: TFDQuery;
begin

  linha := TStringList.Create;
  lista := TStringList.Create;

   NomeDoLog := ExtractFilePath(Application.ExeName) + 'log\jsonPSyncBack_20062017_1933.json';
   AssignFile(Arquivo, NomeDoLog);
   Rewrite(Arquivo);

   lista.LoadFromFile(ExtractFilePath(Application.ExeName) + 'log\jsonPSyncBack_20062017_1933.json');

   while (not eof(Arquivo)) do
     begin
       readln(Arquivo, texto);
       linha.Delimiter := '|';
       linha.StrictDelimiter := true;
       linha.DelimitedText := texto;
       JSON := linha[0];
       nrCoo := linha[1];
       idCaixa := linha[2];
       cdEmp := linha[3];

      // MyThread := TThread.CreateAnonymousThread(procedure begin

            qryTeste := nil;
            qryTeste := TFDQuery.Create(qryTeste);
            qryTeste.Connection := DtmPSyncBack.conPlatinum;

            HTTP := TIdHTTP.Create;
            try
              try

               RequestBody := TStringStream.Create(JSON,TEncoding.UTF8);
                try
                  HTTP.Request.Accept := 'application/json';
                  HTTP.Request.ContentType := 'application/json;charset=utf-8;';
                  HTTP.Request.BasicAuthentication := true;
                  HTTP.Request.Connection  := 'keep-alive';

                  ResponseBody := UTF8ToString(HTTP.Post('http://user:pass@host:port/api/teste/pedido/inclui',RequestBody));

                  qryTeste.Close;

                  qryTeste.SQL.Text := 'insert into tbl_adm_logintegracao (cd_empresa,nr_coo,nr_idcaixa,tp_log,ds_log,ds_json,ds_pedidov,dt_cadastro)'+
                                      ' values ('+#39 +cdEmp+#39+','+#39 +nrCoo+#39+','+#39 +idCaixa+#39+','+#39 +'OK'+#39+','+#39 +'OK'+#39+','+
                                      #39 +JSON+#39+','+#39 +ResponseBody+#39+',CURRENT_TIMESTAMP)';
                  qryTeste.ExecSQL;

                finally
                  RequestBody.Free;
                end;
              except
                on E: EIdHTTPProtocolException do
                begin

                  qryTeste.Close;

                  qryTeste.SQL.Text := 'insert into tbl_adm_logintegracao (cd_empresa,nr_coo,nr_idcaixa,tp_log,ds_log,ds_json,dt_cadastro)'+
                                      ' values ('+#39 +cdEmp+#39+','+#39 +nrCoo+#39+','+#39 +idCaixa+#39+','+#39 +'ERRO'+#39+','+#39+E.ErrorMessage+#39+','+
                                      #39 +JSON+#39+',CURRENT_TIMESTAMP)';
                  qryTeste.ExecSQL;

                end;
                on E: Exception do
                begin
                end;
              end;
            finally
              HTTP.Free;
            end;

        Sleep(100);
      // end).Start;

     end;

   CloseFile(Arquivo);

   linha := nil;

end;

procedure TfrmPSyncBack.Button3Click(Sender: TObject);
var
hThreadID :THandle;
ThreadID :DWord;
begin
  {Cria a Thread, onde @MinhaThread é o Ponteiro da Função criada}
  hThreadID := CreateThread(nil, 0, @MinhaThreadSync, nil, 0, ThreadID);
end;

estou com erro.... 

 

Screenshot_11.png

Link para o comentário
Compartilhar em outros sites

  • 0

sinceramente estou sem saber o que fazer e como solucionar isso, agilizar esse processo, porque se eu mandar varios posts ao mesmo tempo a api aguenta, mas tem que ser por demanda.... :(

 

tentei agora algo mais enxuto....

 

procedure TfrmPSyncBack.Button4Click(Sender: TObject);
var linha: TStringList;
    NomeDoLog, texto: string;
    Arquivo: TextFile;
    nrCoo, idCaixa, cdEmp, JSON: string;
begin

      linha := TStringList.Create;

 NomeDoLog := ExtractFilePath(Application.ExeName) + 'log\jsonPSyncBack_21062017_1232.json';
 AssignFile(Arquivo, NomeDoLog);
 {$I-}
 Reset(Arquivo);
  {$I+}


         while (not eof(Arquivo)) do
         begin

           readln(Arquivo, texto);
           linha.Delimiter := '|';
           linha.StrictDelimiter := true;
           linha.DelimitedText := texto;
           JSON    := linha[0];
           nrCoo   := linha[1];
           idCaixa := linha[2];
           cdEmp   := linha[3];

           TThread.CreateAnonymousThread(procedure begin
             //função de postar o json
             postJSON(linha[0],linha[1],linha[2],linha[3],'VENDA');
             Sleep(100);
           end).Start();


          end;

         CloseFile(Arquivo);
        linha := nil;

end;

mas ele berrou....arquivo com mais de 5300 linhas

 

Screenshot_12.png

Editado por robinhocne
Link para o comentário
Compartilhar em outros sites

  • 0

o código que te passei, foi compilado em delphi 7 e não tem nenhum erro.

 

Screenshot_11.png

vou te passar mais alguns exemplos .. espero que possa te ajudar

http://www.del123.com/DelphiThreadsExample.zip

https://www.thoughtco.com/synchronizing-threads-and-gui-delphi-application-1058159

http://www.delphicorner.f9.co.uk/articles/op4.htm

http://www.componentace.com/multi-thread-delphi.htm

abraço

 

Link para o comentário
Compartilhar em outros sites

  • 0

ok...meu amigo, fiz um exemplo bem simples e visual, para mostrar o que acontece

procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   teste0 := MinhaThread.Create();
   teste0.Execute;
   teste1 := MinhaThread.Create();
   teste1.Execute;
   teste2 := MinhaThread.Create();
   teste2.Execute;
   teste3 := MinhaThread.Create();
   teste3.Execute;

    for i := 1 to 100 do
       begin
          Memo2.lines.append(inttostr(i));
          sleep(5);
       end;

end;

observe que as threads deverão ser executadas antes que o  comando For ( loop ) seja executado, mostrando a sequencia de numeros de 1 a 100 no Memo2

observe tambem que dividi o trabalho em mais de uma thread e aumentei a prioridade de execução da thread para alta

quando voce não usa componentes visuais isso é muito mais rápido.

espero que consiga entender a lógica do processo

codigo completo:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
   MinhaThread = class(TThread)
   procedure Execute; override;
   procedure Verifica;
   procedure Rotina0;
   procedure Rotina1;
   procedure Rotina2;
   procedure Rotina3;
   procedure Fechar;
   Private
   constructor Create();
end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    Teste0: MinhaThread;
    Teste1: MinhaThread;
    Teste2: MinhaThread;
    Teste3: MinhaThread;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

procedure MinhaThread.Execute;
Var Sender : TObject;
begin

   synchronize(Verifica);
   synchronize(Rotina0);

   while not Terminated do
    begin
        Sleep (5);
        Terminate;
        Form1.Memo1.Lines.Append('Thread Finalizada');
        synchronize(Fechar);
    end;

end;

procedure MinhaThread.Verifica;
begin
   Form1.Caption := 'TESTE';
end;

procedure MinhaThread.Fechar;
begin
   application.terminate;
end;

constructor MinhaThread.Create();
begin
  inherited Create(True); { Chama o contrutor herdado. Ele irá temporariamente colocar o thread em estado de espera para depois executá-lo. }
  FreeOnTerminate := True; // Libera o objeto após terminar.
  Priority := tpHigher; { Configura sua prioridade na lista de processos do Sistema operacional. }
  //Resume; // Inicia o Thread.
  //Terminate;
end;

//================================================================================

procedure MinhaThread.Rotina0;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo1.lines.append(inttostr(i));
          sleep(5);
       end;
end;

procedure MinhaThread.Rotina1;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo1.lines.append(inttostr(i));
          sleep(5);
       end;
end;

procedure MinhaThread.Rotina2;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo1.lines.append(inttostr(i));
          sleep(5);
       end;
end;

procedure MinhaThread.Rotina3;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo1.lines.append(inttostr(i));
          sleep(5);
       end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   teste0 := MinhaThread.Create();
   teste0.Execute;
   teste1 := MinhaThread.Create();
   teste1.Execute;
   teste2 := MinhaThread.Create();
   teste2.Execute;
   teste3 := MinhaThread.Create();
   teste3.Execute;

    for i := 1 to 100 do
       begin
          Memo2.lines.append(inttostr(i));
          sleep(5);
       end;

end;

end.

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Uma coisa que não entendi é que nesse caso só executa a rotina 0 4 vezes, as demais não executa, se colocar as demais no syncronize do execute ai executa as 4, 4 vezes. 

O que não estou conseguindo fazer é como criar x thread diferentes que cada uma executa x rotina diferente e esperar que essas x termine para iniciar mais.

Link para o comentário
Compartilhar em outros sites

  • 0

O que não estou conseguindo fazer é como criar x thread diferentes que cada uma executa x rotina diferente e esperar que essas x termine para iniciar mais.

ok... a idéia era essa ....

então vamos as modificações no código

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
   MinhaThread0 = class(TThread)
   procedure Execute; override;
   procedure Rotina0;
   procedure Verifica;
   procedure Fechar;
   Private
   constructor Create();
end;

type
   MinhaThread1 = class(TThread)
   procedure Execute; override;
   procedure Rotina1;
   procedure Verifica;
   procedure Fechar;
   Private
   constructor Create();
end;

type
   MinhaThread2 = class(TThread)
   procedure Execute; override;
   procedure Rotina2;
   procedure Verifica;
   procedure Fechar;
   Private
   constructor Create();
end;

type
   MinhaThread3 = class(TThread)
   procedure Execute; override;
   procedure Rotina3;
   procedure Verifica;
   procedure Fechar;
   Private
   constructor Create();
end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    Memo3: TMemo;
    Memo4: TMemo;
    Memo5: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    Teste0: MinhaThread0;
    Teste1: MinhaThread1;
    Teste2: MinhaThread2;
    Teste3: MinhaThread3;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

procedure MinhaThread0.Execute;
Var Sender : TObject;
begin

   synchronize(Verifica);
   Rotina0;

   while not Terminated do
    begin
        Sleep (5);
        Terminate;
        Form1.Memo1.Lines.Append('Thread Finalizada');
        synchronize(Fechar);
    end;

end;

procedure MinhaThread0.Verifica;
begin
   Form1.Caption := 'TESTE';
end;

procedure MinhaThread0.Fechar;
begin
   application.terminate;
end;

constructor MinhaThread0.Create();
begin
  inherited Create(True); { Chama o contrutor herdado. Ele irá temporariamente colocar o thread em estado de espera para depois executá-lo. }
  FreeOnTerminate := True; // Libera o objeto após terminar.
  Priority := tpHigher; { Configura sua prioridade na lista de processos do Sistema operacional. }
  //Resume; // Inicia o Thread.
  //Terminate;
end;

//================================================================================

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

procedure MinhaThread1.Execute;
Var Sender : TObject;
begin

   synchronize(Verifica);
   Rotina1;

   while not Terminated do
    begin
        Sleep (5);
        Terminate;
        Form1.Memo2.Lines.Append('Thread Finalizada');
        synchronize(Fechar);
    end;

end;

procedure MinhaThread1.Verifica;
begin
   Form1.Caption := 'TESTE';
end;

procedure MinhaThread1.Fechar;
begin
   application.terminate;
end;

constructor MinhaThread1.Create();
begin
  inherited Create(True); { Chama o contrutor herdado. Ele irá temporariamente colocar o thread em estado de espera para depois executá-lo. }
  FreeOnTerminate := True; // Libera o objeto após terminar.
  Priority := tpHigher; { Configura sua prioridade na lista de processos do Sistema operacional. }
  //Resume; // Inicia o Thread.
  //Terminate;
end;

//================================================================================
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

procedure MinhaThread2.Execute;
Var Sender : TObject;
begin

   synchronize(Verifica);
   Rotina2;

   while not Terminated do
    begin
        Sleep (5);
        Terminate;
        Form1.Memo3.Lines.Append('Thread Finalizada');
        synchronize(Fechar);
    end;

end;

procedure MinhaThread2.Verifica;
begin
   Form1.Caption := 'TESTE';
end;

procedure MinhaThread2.Fechar;
begin
   application.terminate;
end;

constructor MinhaThread2.Create();
begin
  inherited Create(True); { Chama o contrutor herdado. Ele irá temporariamente colocar o thread em estado de espera para depois executá-lo. }
  FreeOnTerminate := True; // Libera o objeto após terminar.
  Priority := tpHigher; { Configura sua prioridade na lista de processos do Sistema operacional. }
  //Resume; // Inicia o Thread.
  //Terminate;
end;

//================================================================================
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

procedure MinhaThread3.Execute;
Var Sender : TObject;
begin

   synchronize(Verifica);
   Rotina3;

   while not Terminated do
    begin
        Sleep (5);
        Terminate;
        Form1.Memo4.Lines.Append('Thread Finalizada');
        synchronize(Fechar);
    end;

end;

procedure MinhaThread3.Verifica;
begin
   Form1.Caption := 'TESTE';
end;

procedure MinhaThread3.Fechar;
begin
   application.terminate;
end;

constructor MinhaThread3.Create();
begin
  inherited Create(True); { Chama o contrutor herdado. Ele irá temporariamente colocar o thread em estado de espera para depois executá-lo. }
  FreeOnTerminate := True; // Libera o objeto após terminar.
  Priority := tpHigher; { Configura sua prioridade na lista de processos do Sistema operacional. }
  //Resume; // Inicia o Thread.
  //Terminate;
end;

//================================================================================



procedure MinhaThread0.Rotina0;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo1.lines.append(inttostr(i));
          //sleep(1);
       end;
end;

procedure MinhaThread1.Rotina1;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo2.lines.append(inttostr(i));
          //sleep(1);
       end;
end;

procedure MinhaThread2.Rotina2;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo3.lines.append(inttostr(i));
          //sleep(1);
       end;
end;

procedure MinhaThread3.Rotina3;
var i : integer;
begin
    for i := 1 to 100 do
       begin
          Form1.Memo4.lines.append(inttostr(i));
          //sleep(1);
       end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
begin
   teste0 := MinhaThread0.Create();
   teste0.Execute;
   teste1 := MinhaThread1.Create();
   teste1.Execute;
   teste2 := MinhaThread2.Create();
   teste2.Execute;
   teste3 := MinhaThread3.Create();
   teste3.Execute;

    for i := 1 to 100 do
       begin
          Memo5.lines.append(inttostr(i));
          sleep(5);
       end;

end;

end.

agora voce coloca 5 Memos no Form e um botão .... rode e veja o que acontece

isso poderia ser muito mais simplificado, mas quero que  voce entenda o processo

OBS: se voce colocar no lugar do sleep(1) que esta como comentário,  um sleep(5) só para diminuir um pouco o processamento, voce vai notar que ele vai colocar o resultado em um Memo de cada vez.

mas o ideal é que todos os threads comecem juntos, sem que precise terminar um para começar o outro. ( mas tem que esperar o ultimo thread terminar, pois certamente haverá diferença de tempo na execução ).

abraço

 

Link para o comentário
Compartilhar em outros sites

  • 0

Boa noite, desculpe a demora Jhonas, mas hoje fiquei fora, nesse caso então terei que criar várias threads para dividir o processo, no loop onde percorro os registros terei que passar cada um para uma thread no final do processo de todas terei que verificar se existe mais para fazer o mesmo processo, acho que entendi....ficará grande criar umas 10 pelo menos, mas já vou mandar 10 posts ao mesmo tempo para a api, pelo menos os 10 vai me retornar mais rapido do que mandando 1 há 1.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...