开发者

Why this thread freezes my app on destruction?

开发者 https://www.devze.com 2023-03-26 09:40 出处:网络
I\'m sure it\'s related to the GetMessage call as if I replace it with \'while(not开发者_运维百科 terminated) do;\', the app\'d close peacefully. Is it because GetMessage freezes the thread? Could you

I'm sure it's related to the GetMessage call as if I replace it with 'while(not开发者_运维百科 terminated) do;', the app'd close peacefully. Is it because GetMessage freezes the thread? Could you give more info about the problem itself and eventually a solution. Thanks!

type TListener = class(TThread)
  procedure Execute; override;
  destructor Destroy; override;
end;

var l: TListener;
    msg:TMsg;

procedure TListener.Execute;
begin
  while(not Terminated) do
    while(GetMessage(msg, Cardinal(-1), 0, 0)) do;
end;

destructor TListener.Destroy;
begin
  inherited; // <-- freeze here!
end;

begin
  l:= TListener.Create();
  sleep(1000);
  l.Free;
end.


Consider the termination condition of your inner loop. GetMessage blocks until a message arrives, and it only returns False when it processes a wm_Quit message.

The thread that calls Free on your TThread is waiting for the other thread to terminate — TThread.Destroy calls WaitFor. But your thread never terminates because it evidently never receives a wm_Quit message.

Since you're already using messages, don't bother checking Terminated. That only checks whether someone has called Terminate on your thread object, but since doing so clearly isn't the way to notify the thread that it should stop running, it's pointless to check it. (If the Terminate method were virtual, you could override it and have it post a wm_Quit message to the thread, but it isn't, so you can't.)

0

精彩评论

暂无评论...
验证码 换一张
取 消