Подтвердить что ты не робот

Как убить поток в delphi?

В delphi метод в TThread завершается. Кажется, что subthread не может убить другой поток, вызвав завершение или освобождение. Например A (основная форма), B (единица потока), C ​​(другая форма).

B отправляет данные в основную форму и C (вызывая syncronize), мы пытались завершить B внутри C, пока B выполняет вызовы B.terminate. Но этот метод не работает, и B все еще работает до тех пор, пока он не завершится в методе выполнения.

Пожалуйста, помогите. Заранее благодарю вас.

4b9b3361

Ответ 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

Если вам может потребоваться прекратить поток, тогда вам может быть лучше не создавать другое приложение и убить его, если вы считаете, что его неудачные окна затем уберут после вас.