Почему мой поток продолжает ждать до вызова Application.ProcessMessages? Что я делаю не так? - PullRequest
0 голосов
/ 25 октября 2019

Мне нужно запустить несколько блоков потоков одновременно. То, что я пытаюсь сделать, это:

A имеет 197 операций, которые вызывают индивидуально на shellExecute

Я хочу выполнить 4 операции simultanelly

Я могу начать новую операцию, только если выполняется менее 4

Проблемы:

Мне нужно вставить много Application.ProcessMessages, чтобы она работалаи я не знаю, что я делаю неправильно. Я попробовал все, и, кажется, ничего не работает.

Вот код:

procedure TCompress.NewThread(psArgs: PWideChar);
var
  oThread: TThread;
  nCode : DWord;
begin
  oThread :=  TThread.CreateAnonymousThread(
    procedure
    begin
      try
        FNumberOfThreads := FNumberOfThreads +1; 
        ExecuteAndWait(PChar(FsPathCompressor), psArgs, SW_HIDE, nCode);
        //It is just a CreateProcess with WaitForSingleObject(retorno, INFINITE);
      except on E: Exception do
        begin
          raise;
        end;
      end;
    end);

  oThread.OnTerminate := DoOnTerminate;
  oThread.Start;
end;

procedure TspCompress.DoOnTerminate;
begin
  FNumberOfThreads := FNumberOfThreads -1;
end;

function TspCompress.ExecuteBlocks: Boolean;
var
  sArgs : WideString;
  nBlocksCreated, nTotalBlocks: Integer;
begin  
  nTotalBlocks := 197;
  nBlocksCreated := 0;
  while nBlocksCreated < nTotalBlocks do
  begin
    //Needs Application.ProcessMessages to update FNumberOfThreads.
    while (FNumberOfThreads < 4) and (nBlocksCreated < nTotalBlocks) do
    begin
      try

        sArgs := PChar('C:/file.exe');

        NewThread(PWideChar(sArgs));
        //Needs Application.ProcessMessages to start the thread.
        nBlocksCreated := nBlocksCreated + 1;
      except
      on E: Exception do
        begin
          //Do Something
        end;
      end;
    end;
  end;
end;

FNumberOfThreads является частной переменной класса

Это пример кода того, чтоЯ делаю. Проблема не в самом коде, а в концепции Thread.

1 Ответ

0 голосов
/ 31 октября 2019

В конце я просто использовал System.Threading. Установка ThreadPool и использование Parellel.For.

procedure TCompress.MyParallelProcess;
var
  sArgs : WideString;
  nTotalProcess: Integer;
  oPool: TThreadPool;
  nCode: DWord;
begin
  oPool := TThreadPool.Create;  
  try
    oPool.SetMinWorkerThreads(4);
    oPool.SetMaxWorkerThreads(4);  
    nTotalProcess := 197; 
    TParallel.For(1, nTotalProcess, procedure(i: integer)
    begin
      sArgs := PChar('C:/file'+IntToStr(i)+'.exe');
      ExecuteAndWait(PChar(FsPathCompressor), sArgs, SW_HIDE, nCode);
    end, oPool);
  finally
    FreeAndNil(oPool);
  end;
end; 

Помните, это всего лишь пример кода, но я сделал что-то подобное и работает как перчатка. Спасибо всем за помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...