gpt4 book ai didi

delphi - 等待 Thread 实例启动的正确方法是什么

转载 作者:行者123 更新时间:2023-12-03 14:55:52 29 4
gpt4 key购买 nike

TThread实例创建和启动之间,主线程将继续执行代码。如果主线程中的代码依赖于相关线程的完全启动和运行,则它必须以某种方式等待,直到线程 Execute 方法实际启动。

考虑以下代码:

const
WM_MY_ACTION = WM_APP + 10;

type
TWndThread = class(TThread)
protected
fWndHandle: THandle;
IsRunning: boolean;
procedure WndProc(var Msg: TMessage);
procedure Execute; override;
public
Test: integer;
procedure AfterConstruction; override;
procedure DoAction;
end;

procedure TWndThread.AfterConstruction;
begin
inherited;
while not IsRunning do Sleep(100); // wait for thread start up
end;

procedure TWndThread.Execute;
var
Msg: TMsg;
begin
fWndHandle := AllocateHWnd(WndProc);
IsRunning := true;
try
while not Terminated do
begin
if MsgWaitForMultipleObjects(0, nil^, False, 1000, QS_ALLINPUT) = WAIT_OBJECT_0 then
begin
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;
finally
DeallocateHWnd(fWndHandle);
end;
end;

procedure TWndThread.WndProc(var Msg: TMessage);
begin
case Msg.Msg of
WM_MY_ACTION:
begin
inc(Test);
end;
else Msg.Result := DefWindowProc(fWndHandle, Msg.Msg, Msg.WParam, Msg.LParam);
end;
end;

procedure TWndThread.DoAction;
begin
PostMessage(fWndHandle, WM_MY_ACTION, 0, 0);
end;

var
t: TWndThread;
begin
t := TWndThread.Create;
t.DoAction;
t.Terminate;
end;

如果没有等待 IsRunning 标志的循环,DoAction 将无法成功将消息发送到包含的窗口句柄,因为它尚未创建。基本上,WndProc内的inc(Test)不会被触发。

是否有更好的方法来等待线程启动并在 Execute 方法内完成必要的初始化,或者这个解决方案是否足够好?

注意:我知道 AllocateHWndDeallocateHWnd 不是线程安全的,不应该像上面的示例一样在生产代码中使用。

最佳答案

主线程

  1. 创建一个事件。例如,TSimpleEvent 就足以满足您的需求。
  2. 将事件设置为无信号。对于 TSimpleEvent 来说,这是对 ResetEvent 的调用。我预计新创建的 TSimpleEvent 将处于无信号状态,但我一时记不起这个细节。
  3. 创建线程,并在构造函数中传递事件。
  4. 等待事件发出信号。对于 TSimpleEvent 来说,这意味着调用 WaitFor

工作线程

  1. 记下传递给线程构造函数的事件。
  2. 在线程执行开始时,发出事件信号。对于 TSimpleEvent 来说,这意味着调用 SetEvent

关于delphi - 等待 Thread 实例启动的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28608530/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com