Как справедливо заметил Барри, если не вызывается CheckSyncronize, Synchronize не вызывается, а если синхронизация не вызывается, то событие OnTerminate не вызывается. Кажется, что происходит, когда я запускаю свои модульные тесты как консольное приложение, в очереди сообщений нет сообщений, и поэтому Application.ProcessMessage, который вызывается из Processmessages, никогда не вызывает checkSynchronize. Теперь я решил проблему, изменив цикл на
While fThreadRefCount > 0 do
begin
Application.ProcessMessages;
CheckSynchronize;
end;
Теперь он работает как в режиме консоли, так и в графическом режиме.
Кажется, весь хук wakeupmainthread настроен правильно. Именно этот хук отправляет сообщение WM_NULL, которое запускает проверку синхронизации. В консольном приложении это не так уж далеко.
Больше расследований
Итак, Synchronize вызывается . DoTerminate вызывает Synchronize (CallOnTerminate), но там есть строка:
WaitForSingleObject(SyncProcPtr.Signal, Infinite);
, который просто ждет вечно.
Так что, хотя мое исправление выше работает, в этом есть что-то более глубокое!