Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

andregv

Processamento Assíncrono

Recommended Posts

Olá a todos!

 

Tenho um aplicativo de importação de dados para um DB PostgreSQL. O aplicativo funciona perfeitamente.

No final do processo, porém, executo uma Store procedure do PostgreSQL que demora uns 10 minutos (consolidação dos dados). Porém durante esse período, o sistema paralisa, como se estivesse travado.

Alterando o ExecutionOptions da TADOQuery para [eoAsyncExecute, eoAsyncFetch, eoAsyncFetchNonBlocking] eu consigo executar de forma assíncrona (e no caso, se houver mais alguns processos depois... ele ocorrem normalmente).

Meu objetivo é o seguinte... executar o processo de forma assíncrona só para não paralisar o programa, e ficar exibindo uma mensagem ou loading até o processo acabar.

 

ps.: sei que existe o evento OnFetchProgress e OnFetchComplete.... porém não sei como encaixá-lo sistema.

 

Segue o bloco de código onde chamo para executar a procedure:

 

// Executa Stored Procedure que atualiza Eclifor e Ecodrev QTITU
mmLog.Lines.Add(' ');
mmLog.Lines.Add('>> Store Procedure QTitu iniciada: ' + DateTimeToStr(Now));
aNiveis[1] := 'Store Procedure updCodRevQtitu-sem-gatilho()';
SetPriorityClass(GetCurrentProcess, HIGH_PRIORITY_CLASS);
// objeto ADOQuery usado no processo
pgQExec.ExecuteOption := [eoAsyncExecute, eoAsyncFetchNonBlocking];
pgQExec.Close;
pgQExec.SQL.Clear;
pgQExec.SQL.Add('SELECT * FROM "DBPG"."DBConsolide"();');
try
	pgQExec.ExecSQL;
except
	on E: Exception do logErro(E.Message + #13 + sSQL);
end;
pgQExec.Close;
Application.ProcessMessages;
// restaura as opções
pgQExec.ExecuteOption := [eoExecuteNoRecords];
SetPriorityClass(GetCurrentProcess, NORMAL_PRIORITY_CLASS);
mmLog.Lines.Add('>> Store Procedure QTitu concluída: ' + DateTimeToStr(Now));
mmLog.Lines.Add('-----------------------------------------------------------------------------------------');

Desde já agradeço qualquer ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você pode utilizar uma thread..

 

abaixo vou t passa o código de como criar uma classe de thread, depois é so instanciar um objeto:

 

unit UnitThread;

interface

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

type
	TMultlinha = class(TThread)
	private
 	procedure PilhaEstourada;
	protected
 	procedure Execute; override;
 	procedure teste;
end;

implementation

{$R *.dfm}

{ TMultlinha }

procedure TMultlinha.Execute;
{
	esta é a função que é executada de modo assíncrono, neste caso,
	como precisei que esta função ficasse rodando até o fim do
	programa, coloquei um while. Mas se for só um comando é so colocar
	direto. Ele executa os comandos de forma assíncrona e depois "cai fora"
	da execução desta função. Como faz com qualquer outra função
}
begin
 inherited;
 cont := 0;
	while(true) do begin

	inc(cont); //comandos que precisam ser executados em modo assíncrono
	Synchronize(teste); //sincroniza uma função
 end;
end;

procedure TMultlinha.teste;
begin
	form1.label1.caption := inttostr(cont); //para alterar dados dos forma é bom sincronizar uma funãçao
end;

end.

aqui tem um exemplo de como criar o objeto

 

procedure TForm1.Button1Click(Sender: TObject);
begin
MinhaThread := TMultlinha.Create(false);
end;

 

Espero que ajude.

 

:D

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.