使用Synchronize时出现问题

use*_*ser 4 delphi multithreading thread-safety

我需要在一个单独的线程中执行一个函数,并等待线程完成.

例如,这是原始函数:

Procedure Search;
begin
  CallA;
  CallB;
end;
Run Code Online (Sandbox Code Playgroud)

这是修改后的功能:

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.
Run Code Online (Sandbox Code Playgroud)

CallA如果我Synchronize在里面使用,你能告诉我为什么上面的线程代码不起作用(从不被执行)TMyThread.Execute

And*_*jeŭ 5

因为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
Run Code Online (Sandbox Code Playgroud)

  • 这确实是一个解决方案,但实际上应该调整表单以阻止等待线程.毕竟,现在的最终效果是没有任何改变,只添加了复杂功能.应该启动线程,然后IT应该完成工作,然后最后更新UI.它不应该都在一个搜索过程中. (2认同)