使用同步时出现问题

发布于 2024-11-28 18:42:19 字数 1257 浏览 0 评论 0原文

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

例如,这是原始函数:

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.

你能告诉我为什么如果我使用 SynchronizeCallA 永远不会被执行) > 在 TMyThread.Execute 内?

I need to execute a function in a separated thread and wait until the thread is finished.

For example, here's the original function :

Procedure Search;
begin
  CallA;
  CallB;
end;

This is the modified function :

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.

Could you tell me why the thread code above doesn't work (CallA never being executed) if I use Synchronize inside TMyThread.Execute ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南笙 2024-12-05 18:42:19

因为 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

Because Synchronize will call a method within application's message loop. And using WaitForSingleObject you simply put all application on hold. Try this:

  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
云醉月微眠 2024-12-05 18:42:19

Delphi tthread 类有一个名为 onThreadTerminate 的事件。
当线程离开执行方法时,这会在应用程序线程的上下文中调用。

您可以在您的应用程序中使用此事件。

the Delphi tthread class has an event called onThreadTerminate.
This is called in the context of the application thread, when the thread leaves the execute method.

you can use this event in your application.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文