My application has several threads: 1) Main Thread 2) 2 Sub-Main Threads (each with Message Loop, as shown below), used by TFQM 3) n Worker Threads (simple loop, containing Sleep())
My problem is, when I close my application, the Worker Threads manage to exit properly, but 1 of the 2 Sub-Main Threads hangs (never exits) when I issue WM_QUIT to close them.
procedure ThreadProcFQM(P: Integer); stdcall;
var
Msg: TMsg;
_FQM: TFQM;
begin
_FQM := Ptr(P);
try
_FQM.fHandle := AllocateHwnd(_FQM.WndProc);
while GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
finally
DeallocateHWnd(_FQM.fHandle);
SetEvent(_FQM.hTerminated);
end;
end;
procedure TFQM.Stop;
begin
PostMessage(fHandle, WM_QUIT, 0, 0);
WaitForSingleObject(hTerminated, INFINITE);
if hThread <> INVALID_HANDLE_VALUE then
begin
CloseHandle(hThread);
hThread := INVALID_HANDLE_VALUE;
end;
end;
If I may point to few problems in your code ...
1) You're not checking output of AllocateHwnd. Yes, most probably it will never fail, but still ...
2) AllocateHwnd belogs OUT of try..finally! If it fails, DeallocateHwnd should not be called.
3) AllocateHwnd is not threadsafe. If you call it from multiple threads at the same time, you can run into poblems. Read more.
As Davy said, use MsgWaitForMultipleObjects instead of creating hidden message window. Then use PostThreadMessage to send messages to thread.
If I may put a plug for a totally free product here - use my OmniThreadLibrary instead. Much simpler than messing directly with Windows messaging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With