OnIdTCPServerDisconnect works fine when a client disconnected during the server.exe runtime, but Synchronize(@DeleteFromCheckListBox) will block when the server.exe close.
procedure TForm1.FormDestroy;
begin
idTcpSvr.Free;//idTcpSvr.Free will trigger OnIdTCPServerDisconnect event
end;
You can't use TThread.Synchronize() while the main thread is blocked deactivating the server. Server deactivation is a blocking operation, so the main thread will be blocked from processing Synchronize() requests until after deactivation is finished. But the deactivation is blocked waiting for the server threads to terminate, which is waiting on Synchronize() to finish. Deadlock.
So, either:
1. use TThread.Queue() instead of TThread.Synchronize() so the server thread is not blocked during deactivation.
2. deactivate the server in a worker thread so the main thread is not blocked.
In the second case, you can simplify your shutdown code using TThread.WaitFor() instead of a manual message loop, as WaitFor() handles Synchronize() and Queue() requests while waiting:
with TStopThread.Create(True) do
try
par := Self;
Start;
WaitFor;
finally
Free;
end;
Alternatively:
with TThread.CreateAnonymousThread(
procedure
begin
svrDFDev.Active := False;
end
) do
try
FreeOnTerminate := False; // <-- CreateAnonymousThread() sets this to True by default
Start;
WaitFor;
finally
Free;
end;