Demora em processo muito grande
Bom dia,
Tenho 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....
Tenho 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.
Robson Morais
Curtidas 0
Respostas
Fernando Oliveira
20/06/2017
Boa tarde, sou novo por aqui e não tenho tanta experiência quanto outros por aqui, mas já desenvolvi vários softwares sozinho e passei por um problema parecido.
Portanto espero que minha dica ajude...
Veja bem, eu evito ao máximo usar sleep, pois como sabe ele paralisa o programa, só uso ele em situações específicas, prefiro usar um timer de acordo o que for necessário.
Bom a minha aplicação assim como a sua, precisa atualizar várias informações de tempos em tempos entre dois bancos de dados diferentes, então para não ter que fazer isso a cada segundo (o que toma processamento e as vezes vai juntando "sujeira" na memória de pendendo do processo), eu adicionei um campo em uma das tabelas onde o sistema verifica se houve sincronização entre os bancos.
Então a cada x segundos o sistema verifica apenas essa tabela (tabela sync booleana), caso ainda não tenham sido sincronizados os dados ai sim ele faz as transferências, caso contrário ele não faz nada.
Dessa forma consegui reduzir o consumo de processamento.
Espero que ajude.
Abrçs.
Portanto espero que minha dica ajude...
Veja bem, eu evito ao máximo usar sleep, pois como sabe ele paralisa o programa, só uso ele em situações específicas, prefiro usar um timer de acordo o que for necessário.
Bom a minha aplicação assim como a sua, precisa atualizar várias informações de tempos em tempos entre dois bancos de dados diferentes, então para não ter que fazer isso a cada segundo (o que toma processamento e as vezes vai juntando "sujeira" na memória de pendendo do processo), eu adicionei um campo em uma das tabelas onde o sistema verifica se houve sincronização entre os bancos.
Então a cada x segundos o sistema verifica apenas essa tabela (tabela sync booleana), caso ainda não tenham sido sincronizados os dados ai sim ele faz as transferências, caso contrário ele não faz nada.
Dessa forma consegui reduzir o consumo de processamento.
Espero que ajude.
Abrçs.
GOSTEI 0
Fernando Oliveira
20/06/2017
Apenas corrigindo um pequeno erro... onde disse tabela, eu quis diz um campo (Campo Sync Booleano) em uma tabela.
Boa tarde, sou novo por aqui e não tenho tanta experiência quanto outros por aqui, mas já desenvolvi vários softwares sozinho e passei por um problema parecido.
Portanto espero que minha dica ajude...
Veja bem, eu evito ao máximo usar sleep, pois como sabe ele paralisa o programa, só uso ele em situações específicas, prefiro usar um timer de acordo o que for necessário.
Bom a minha aplicação assim como a sua, precisa atualizar várias informações de tempos em tempos entre dois bancos de dados diferentes, então para não ter que fazer isso a cada segundo (o que toma processamento e as vezes vai juntando "sujeira" na memória de pendendo do processo), eu adicionei um campo em uma das tabelas onde o sistema verifica se houve sincronização entre os bancos.
Então a cada x segundos o sistema verifica apenas esse campo (campo sync booleano) em uma tabela do banco onde conteem as informações a serem extraídas , caso ainda não tenham sido sincronizados os dados ai sim ele faz as transferências e insere nessa tabela(sync) um true dizendo que aquela linha já foi exportada, caso contrário ele não faz nada.
Dessa forma consegui reduzir o consumo de processamento.
Espero que ajude.
Abrçs.
Boa tarde, sou novo por aqui e não tenho tanta experiência quanto outros por aqui, mas já desenvolvi vários softwares sozinho e passei por um problema parecido.
Portanto espero que minha dica ajude...
Veja bem, eu evito ao máximo usar sleep, pois como sabe ele paralisa o programa, só uso ele em situações específicas, prefiro usar um timer de acordo o que for necessário.
Bom a minha aplicação assim como a sua, precisa atualizar várias informações de tempos em tempos entre dois bancos de dados diferentes, então para não ter que fazer isso a cada segundo (o que toma processamento e as vezes vai juntando "sujeira" na memória de pendendo do processo), eu adicionei um campo em uma das tabelas onde o sistema verifica se houve sincronização entre os bancos.
Então a cada x segundos o sistema verifica apenas esse campo (campo sync booleano) em uma tabela do banco onde conteem as informações a serem extraídas , caso ainda não tenham sido sincronizados os dados ai sim ele faz as transferências e insere nessa tabela(sync) um true dizendo que aquela linha já foi exportada, caso contrário ele não faz nada.
Dessa forma consegui reduzir o consumo de processamento.
Espero que ajude.
Abrçs.
GOSTEI 0
Robson Morais
20/06/2017
Obrigado pela resposta, mas não seria esse caso mesmo, a carga que estou realizando é historico, então tenho que mandar tudo, depois o processo ira rodar 1 vez por dia por causa de fechamentos financeiros e fiscais, o que preciso aumentar esse processamento....
GOSTEI 0
Emerson Nascimento
20/06/2017
acredito que haja um problema de conceito: se você trabalha com threads, você precisa executar múltiplas vezes a thread, senão não faz sentido.
não sei se entendi o seu processo, mas deveria ser algo assim:
end
da forma apresentada, será criada uma thread para cada registro que será processado. e serão executadas simultaneamente.
você precisara modificar a sua thread para receber o parâmetro e efetuar todo o tratamento de cada registro dentro da thread, juntamente com o idHTTP post e a sincronização das respostas na tela.
entendeu?
não sei se entendi o seu processo, mas deveria ser algo assim:
procedure TForm1.Button1Click(Sender: TObject); begin query.open; while not query.eof begin MinhaThread.Create( query.registro ) query.next; end
end
da forma apresentada, será criada uma thread para cada registro que será processado. e serão executadas simultaneamente.
você precisara modificar a sua thread para receber o parâmetro e efetuar todo o tratamento de cada registro dentro da thread, juntamente com o idHTTP post e a sincronização das respostas na tela.
entendeu?
GOSTEI 0
Robson Morais
20/06/2017
entendi, porque dessa forma a parte mais pesada que é o post e o retorno fica por conta da thread....
porém dentro da thread eu consigo tratar um log (txt) para todas as threads ? ou seria melhor mesmo por banco ?
porém dentro da thread eu consigo tratar um log (txt) para todas as threads ? ou seria melhor mesmo por banco ?
GOSTEI 0
Emerson Nascimento
20/06/2017
entendi, porque dessa forma a parte mais pesada que é o post e o retorno fica por conta da thread....
porém dentro da thread eu consigo tratar um log (txt) para todas as threads ? ou seria melhor mesmo por banco ?
porém dentro da thread eu consigo tratar um log (txt) para todas as threads ? ou seria melhor mesmo por banco ?
você consegue, sim, tratar o log num arquivo txt. o nome do arquivo pode ser um dos parâmetros da thread, por exemplo. mas será necessário proteger o código para não acontecer falha na abertura simultânea do arquivo.
se puder gravar o log no banco fica melhor, porque cada iteração será um novo registro, não havendo problema de bloqueio.
GOSTEI 0
Robson Morais
20/06/2017
estou tentando fazer dessa forma;
dados do json
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....
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 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....
GOSTEI 0
Emerson Nascimento
20/06/2017
deveria ser algo assim:
thread:
exemplo de uso da thread:
eu fiz tudo pelo bloco de notas (estou sem o Delphi na máquina) então pode ser que necessite corrigir erros no código.
thread:
type
MinhaThread = class(TThread)
private
conexao: TSQLConnetion;
qryTeste: TFDQuery;
HTTP: TIdHTTP;
RequestBody: TStream;
nrCoo, idCaixa, cdEmp, JSON, ResponseBody: string;
protected
procedure Execute; override;
public
constructor Create(const sqlConexao: TSQLConnection; strnrCoo, stridCaixa, strcdEmp, strJSON: string);
destructor Destroy; override;
end;
{ MinhaThread }
constructor MinhaThread.Create(const sqlConexao: TSQLConnection; strnrCoo, stridCaixa, strcdEmp, strJSON: string);
begin
inherited Create( True ); // cria suspensa
// atribui o conteúdo dos parâmetros às 'propriedades' da thread
Self.conexao := sqlConexao;
Self.nrCoo := strnrCoo;
Self.idCaixa := stridCaixa
Self.cdEmp := strcdEmp
Self.JSON := strJSON
// cria os objetos necessários
Self.qryTeste := TFDQuery.Create(nil);
Self.qryTeste.Connection := Self.conexao
Self.HTTP := TIdHTTP.Create;
// configura as propriedades da thread
FreeOnTerminate := True;
Priority := tpLower;
// executa a thread
Resume;
end;
procedure MinhaThread.Execute;
begin
try
Self.RequestBody := TStringStream.Create(Self.JSON,TEncoding.UTF8);
Self.HTTP.Request.Accept := 'application/json';
Self.HTTP.Request.ContentType := 'application/json;charset=utf-8;';
Self.HTTP.Request.BasicAuthentication := true;
Self.HTTP.Request.Connection := 'keep-alive';
Self.ResponseBody := UTF8ToString(HTTP.Post('http://user:password@host:port/api/teste/pedido/inclui',Self.RequestBody));
Self.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 +Self.cdEmp+#39+','+#39 +Self.nrCoo+#39+','+#39 +Self.idCaixa+#39+','+#39 +'OK'+#39+','+#39 +'OK'+#39+','+
#39 +Self.JSON+#39+','+#39+Self.ResponseBody+#39+',CURRENT_TIMESTAMP)';
Self.qryTeste.ExecSQL;
except
on E:Exception do
begin
Self.qryTeste.SQL.Text := 'insert into tbl_adm_logintegracao (cd_empresa,nr_coo,nr_idcaixa,tp_log,ds_log,ds_json,dt_cadastro)'+
' values ('+#39 +Self.cdEmp+#39+','+#39 +Self.nrCoo+#39+','+#39 +Self.idCaixa+#39+','+#39 +'ERRO'+#39+','+#39+E.ErrorMessage+#39+','+
#39 +Self.JSON+#39+',CURRENT_TIMESTAMP)';
Self.qryTeste.ExecSQL;
end;
end;
end;
destructor MinhaThread.Destroy;
begin
FreeAndNil(Self.qryTeste);
FreeAndNil(Self.HTTP);
FreeAndNil(Self.RequestBody);
FreeAndNil(Self.ResponseBody);
inherited Destroy;
end;
exemplo de uso da thread:
procedure TfrmPSyncBack.Button2Click(Sender: TObject);
var
linha, lista: TStringList;
NomeDoLog, texto: string;
Arquivo: TextFile;
nrCoo, idCaixa, cdEmp, JSON: string;
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];
MinhaThread.Create( DtmPSyncBack.conPlatinum, nrCoo, idCaixa, cdEmp, JSON );
end;
CloseFile(Arquivo);
linha := nil;
end;
eu fiz tudo pelo bloco de notas (estou sem o Delphi na máquina) então pode ser que necessite corrigir erros no código.
GOSTEI 0
Robson Morais
20/06/2017
boa tarde, unico ajustes que realizei foi no create, utilizei de um datamodule que ja tenho toda a conexão com o firebird, porque não consegui criar em tempo de execução...
mas acredito que o erro que está dando não seja por isso....
Thread creation erro: Espaço insuficiente de armazenamento para processar este comando.
o Arquivo tem mais de 5.000 linhas tenho casos de arquivo com mais de 50.000 linhas, então acho que deve estar dando estouro por isso...
constructor MinhaThread.Create(strnrCoo,
stridCaixa, strcdEmp, strJSON: string);
begin
inherited Create(True); // cria suspensa
Self.nrCoo := strnrCoo;
Self.idCaixa := stridCaixa;
Self.cdEmp := strcdEmp;
Self.JSON := strJSON;
// cria os objetos necessários
Self.qryTeste := TFDQuery.Create(nil);
Self.qryTeste.Connection := DtmPSyncBack.conPlatinum;
Self.HTTP := TIdHTTP.Create;
// configura as propriedades da thread
FreeOnTerminate := True;
Priority := tpLower;
// executa a thread
Resume;
end;mas acredito que o erro que está dando não seja por isso....
Thread creation erro: Espaço insuficiente de armazenamento para processar este comando.
o Arquivo tem mais de 5.000 linhas tenho casos de arquivo com mais de 50.000 linhas, então acho que deve estar dando estouro por isso...
GOSTEI 0