Первое правило заключается в том, что основные методы исполнителя потоков должны быть написаны так, чтобы их можно было правильно сигнализировать и завершать работу, а второе правило заключается в том, что вам не следует сначала просто отключить основной поток приложения, а затем надеяться, чтодругие потоки закрываются в свое время, чтобы быть в безопасности, вы должны дать сигнал всем фоновым потокам прекратить работу, дождаться завершения этого завершения и ТОГДА завершить работу основного потока.Пример минимальной THREAD:
procedure TMyThread.Execute;
begin
Init;
while not Terminated do
OneWorkItem; // inside OneWorkItem, you ALSO need to check for Terminated
end;
Пример минимальной основной формы / основного потока:
procedure TMyMainForm.CheckAndShutdown;
begin
if FPendingShutdownFlag then
if AllBackgroundThreadsTerminated then
Self.Close;
end;
Вы можете установить FPendingShutdownFlag и вызвать указанную выше функцию из цикла обработки в режиме ожидания приложения.Когда пользователь нажимает на основную форму FormClose, если AllBackgroundThreadsTeridity возвращает значение false, установите для CanClose значение false и установите вместо него FPendingShutdownFlag := true
.
Если вы выполняете бесконечный цикл (при значении true), приложение не выполняетОтключи чисто, даже если тебе так кажется.Каким-то образом приложение завершается, и запущенные потоки могут просто внезапно тихо уходить, или они могут блокировать вас или иным образом вызывать сбой, поскольку они могут использовать ресурсы в потоке 2, которые вы заняты освобождением в потоке 1.
У вас может быть одно или несколько преднамеренных состояний состязания, потому что вы, возможно, не написали свой метод выполнения потока как прерываемый, или вы можете начать закрытие основного потока приложения и VCL и его объектов, прежде чем будете уверены, что ваш фонтемы полностью закрыты.