Как убить поток в delphi?
В delphi метод в TThread завершается. Кажется, что subthread не может убить другой поток, вызвав завершение или освобождение.
Например
A (основная форма), B (единица потока), C (другая форма).
B отправляет данные в основную форму и C (вызывая syncronize), мы пытались завершить B внутри C, пока B выполняет вызовы B.terminate. Но этот метод не работает, и B все еще работает до тех пор, пока он не завершится в методе выполнения.
Пожалуйста, помогите. Заранее благодарю вас.
Ответы
Ответ 1
Вы должны проверить на Terminate в потоке, чтобы это работало. Например:
procedure TMyThread.Execute;
begin
while not Terminated do begin
//Here you do a chunk of your work.
//It important to have chunks small enough so that "while not Terminated"
//gets checked often enough.
end;
//Here you finalize everything before thread terminates
end;
С помощью этого можно вызвать
MyThread.Terminate;
И он прекратится, как только он завершит обработку другого фрагмента работы. Это называется "изящным прекращением потока", потому что сам поток имеет возможность завершить любую работу и подготовиться к завершению.
Существует еще один метод, называемый принудительным завершением. Вы можете позвонить:
TerminateThread(MyThread.Handle);
При этом Windows принудительно останавливает любую активность в потоке. Это не требует проверки "Прекращено" в потоке, но потенциально может быть чрезвычайно опасным, потому что вы убиваете поток в середине операции. После этого может произойти сбой приложения.
Вот почему вы никогда не используете TerminateThread, пока не убедитесь, что у вас есть все возможные последствия. В настоящее время вы этого не делаете, поэтому используйте первый метод.
Ответ 2
Terminate не убивает нить; он устанавливает свойство Terminated
, чтобы сообщить поток, который он должен завершить. Это ответственность за резьбу для Terminated
и изящно закрыть себя.
Ответ 3
На самом деле,
в настоящее время большинство голосовавших ответов на этот вопрос неверно (так как 34 активиста...) в отношении того, как принудительно убить поток.
Вы не используете ThreadId
как параметр процедуры TerminateThread
. Использование ThreadId
приведет к тому, что скорее всего ошибка "Недопустимый дескриптор" или в худшем случае scenerio - убьет другой поток.
Вы должны передать описатель потока в качестве параметра:
TerminateThread(MyThread.Handle);
Подробнее о различиях между дескриптором потока и идентификатором можно найти здесь.
Edit
Кажется, @himself исправил свою ошибку, увидев мой ответ, так что это уже не актуально.
Ответ 4
Весь метод Terminate
делает это, если для свойства Terminated
установлено значение true. Поэтому вам нужно вручную проверить это свойство и затем выйти из метода потока, если для него установлено значение true.
Ответ 5
Если вам может потребоваться прекратить поток, тогда вам может быть лучше не создавать другое приложение и убить его, если вы считаете, что его неудачные окна затем уберут после вас.