Проблема с использованием синхронизации - PullRequest
4 голосов
/ 11 августа 2011

Мне нужно выполнить функцию в отдельном потоке и дождаться завершения потока.

Например, вот оригинальная функция:

Procedure Search;
begin
  CallA;
  CallB;
end;

Это модифицированная функция:

Procedure Search;
var
  testMyThread: TMyThread;
  Done: Boolean;
begin
  // create a new thread to execute CallA
  testMyThread:=TMyThread.Create(False,Done);
  WaitForSingleObject(testMyThread.Handle, INFINITE );
  if not Done then
  begin
    TerminateThread(testMyThread.Handle, 0);
  end
  else;  
  CallB;
end

unit uMyThread;

interface

uses classes;

type
  TMyThread = class(TThread)
  private
    { Private declarations }
    FDone: ^boolean;
  protected
    procedure Execute; override;
  public
    constructor Create(const aSuspended: boolean; var Done: boolean);
    procedure CallA;
  end;

implementation

uses uMain;

constructor TMyThread.Create(const aSuspended: boolean;
  var Done: boolean);
begin
  inherited Create(aSuspended);
  FDone := @Done;
end;

procedure TMyThread.CallA;
begin
  // enumurating several things + updating the GUI
end;

procedure TMyThread.Execute;
begin
  inherited;
  Synchronize(CallA); // << the problem
  FDone^ := true;
end;
end.

Не могли бы вы сказать мне, почему приведенный выше код потока не работает (CallA никогда не выполняется), если я использую Synchronize внутри TMyThread.Execute?

Ответы [ 2 ]

5 голосов
/ 11 августа 2011

Потому что Synchronize вызовет метод в цикле сообщений приложения.А используя WaitForSingleObject, вы просто приостанавливаете все приложения.Попробуйте это:

  Procedure Search;
  var
    testMyThread: TMyThread;
    Done: Boolean;
  begin
    // create a new thread to execute CallA
    testMyThread:=TMyThread.Create(False,Done);

    while (not Done) and (not Application.Terminated) do
      Application.ProcessMessages;

    if not Application.Terminated then
      CallB;
  end
1 голос
/ 11 августа 2011

В классе Delphi tthread есть событие onThreadTerminate. Это вызывается в контексте потока приложения, когда поток покидает метод execute.

Вы можете использовать это событие в своем приложении.

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