Run Thread Serialized

Asked

Viewed 41 times

0

I have the following question:

1 - I have a routine that runs through a database, which has file information you need without writing, may have up to 100 records.

2 - The application needs to go through the record, and collect the information, and write the files.

3 - The files to be written can be large size.

4 - Need to be written sequentially, ie every written file, hence then the application will go to the next.

I developed the code below using Thread.

Problems:

1 - As it is all Jobs, are executed at the same time, As I understood, can not happen, because if the database is too large, the memory consumption by JOB, is immense.

I need that even if you are using the concept of Thread parallelism, this routine works serialized, that is, record by record, only when one Thread is finished, the other can start.

I tried using Waitfor, but as it is in the main process locked the application, thing that can not happen.

I tried several possibilities but I couldn’t, could someone give me a hint on how to do this? Run Thread sequentially, but with parallelism?

while not dm.quArquivos do 
begin 
nControleThreads := nControleThreads + 1; 
thEscreveArquivo:= tEscreveArquivo.Create(True); 
thEscreveArquivo.sDriverId := dm.quBancoTIPO_BANCO.AsString; 
thEscreveArquivo.sDataBase := dm.quBancoDATABASE.AsString; 
thEscreveArquivo.sOwner := dm.quBancoOWNER.AsString; 
thEscreveArquivo.sServer := dm.quBancoSERVIDOR.AsString; 
thEscreveArquivo.sipserver := dm.quBancoIP.AsString; 
thEscreveArquivo.sPort := dm.quBancoPORTA.AsString; 
thEscreveArquivo.sCharacterSet := 'utf8'; 
thEscreveArquivo.sUserName := dm.quBancoUSUARIO.AsString; 
thEscreveArquivo.sPassWord := dm.quBancoSENHA.AsString; 
thEscreveArquivo.sTodosDatabase := 
dm.quBancoTODOS_DATABASE.AsString; 
thEscreveArquivo.sNomeArquivo := sNomeArquivoOrigem; 
thEscreveArquivo.sNomeArquivoZip := sNomeArquivoZipDestino; 
thEscreveArquivo.sSenhaCritpoGrafia := 
dm.quConfigsenha_criptografia.AsString; 
thEscreveArquivo.sAlias := dm.quBancoALIAS.AsString; 
thEscreveArquivo.sCaminho := sCaminho; 
thEscreveArquivo.IidBanco := dm.quBancoID.AsInteger; 
thEscreveArquivo.FreeOnTerminate := True; 
thEscreveArquivo.OnTerminate := ControleThreads; 
thEscreveArquivo.Start; 

Sleep(2000); 
dm.quArquivos.Next; 
end;
  • If one can be written ONLY when the other is done, what is the point of using thread?

  • The point would be simply not to stop implementation, as the process is cumbersome and time-consuming.

1 answer

0

If the intention is just not to lock the application. Try as follows:

var
  vTarefa: TThread;
begin
  vTarefa := TThread.CreateAnonymousThread(
    procedure
    begin
      ... // Faça todo procedimento aqui  
    end);

  vTarefa.Start;
  while vTarefa.Finished = False then
    Application.ProcessMessages;
end;

Note that we created a "task" and left the application waiting for it to end. As there is a "Processmessages" the application is in Idle waiting. This process is bad because it raises the level of processing of the application.

The Ideal will be you pause the while for a few milesseconds... something like:

while vTarefa.Finished = False then
begin
  Sleep(10) // Aqui você precisa medir quanto precisa, geralmente 10 é suficiente
  Application.ProcessMessages;
end;

If you are in Xe10 it is much better to use Task

  • Good morning Junior. Thanks for the support, I will validate and return.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.