Предположим, что у нас есть один вторичный поток. Что он делает - не важно. Важно то, что внутри него имеется метод, который выполняется через синхронизацию, т.е. выполняется во внешнем потоке.
Далее, если вдруг началось завершение программы, мы должны завершить второстепенный поток, чтобы освободить всё что он там наделал и завершить уже программу.
Проблема в следующем: Если вторичный поток в момент завершения программы ждал сигнал на синхронизацию, т.е. он был готов выполнить метод через синхронизацию, но ждал, пока основной поток позволит, то в итоге получается взаимная блокировка, т.к. основной поток ждет завершения второстепенного, а второстепенный ждёт синхронизации от основного.
if Assigned(FThread) then
begin
FThread.Terminate;
FThread.Free; <- тут, при освобождении потока выполняется WaitFor для этого потока
FThread := nil;
end;
Ещё раз, при FThread.Free; основной поток ждёт (WaitFor) завершение второстепенного потока, который ждёт синхронизации с основным потоком.
Я пробовал ещё так:
if Assigned(FThread) then
begin
FThread.Terminate;
TThread.Current.Yield; //с или без этого
while not FLongPollStopped do <- флаг, который меняет второстепенный поток при завершении
begin
CheckSynchronize(10000); //с или без этого
Application.ProcessMessages;
end;
FThread.Free;
FThread := nil;
end;