Исправить нить уничтожить - PullRequest
5 голосов
/ 24 сентября 2010

Hello В моей форме я создаю TFrame во время выполнения. В этом кадре я создаю фоновый поток с выполнением команд в бесконечном цикле. Но когда я разрушу этот кадр, я должен уничтожить этот поток. Я стараюсь

thread.Suspend;
thread.Terminate;
FreeAndNil(thread);

но получите AV и ThreadError. Как мне уничтожить нить?

Ответы [ 3 ]

13 голосов
/ 24 сентября 2010

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

Код может быть примерно таким:

procedure TThread.Execute;
begin
  while not Self.Terminated do
  begin
    //do something
  end;
end;

Вызывайте это, когда хотите уничтожить нить:

thread.Terminate;
thread.WaitFor;
FreeAndNil(thread);
4 голосов
/ 26 сентября 2010

Вы никогда не должны вызывать suspend для tthread, так как это небезопасно, и резюме следует использовать только для запуска потока, который был создан как приостановленный.

В Delphi 2010 приостановлено и возобновлено там, где амортизация и запуск метода были введены, чтобы усилить это.

Более полное объяснение см. В этой теме на форумах Codegears.

сказав, что есть 2 способа прекратить и освободить поток.

1: я устанавливаю FreeOnTerminate при создании потока, поэтому я просто вызываю.

Thread.Terminate;

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

Thread.Terminate;
Thread.WaitFor;
//Do somthing like read a public property from thread object
if Thread <> nil then FreeAndNil(Thread);

В главном цикле выполнения, возможно, было бы неплохо добавить некоторую обработку исключений. Или вас может удивить, почему поток, по-видимому, завершает свою собственную работу.Это может вызывать AV, если для потока задано значение FreeOnTerminate, и оно уже было освобождено при попытке освободить его.

procedure TThread.Execute;
begin
  while not Terminated do
  begin
    try
      //do something
    except
      on E:Exception do
       //handle the exception
    end;
  end;
end; 
4 голосов
/ 24 сентября 2010

Достаточно сделать thread.Terminate.Но вы, вероятно, захотите установить thread.FreeOnTerminate := true при его создании.

Конечно, в жестком цикле вашего потока (то есть в Execute) вам необходимо проверить, был ли потокзапрошено прекратить (проверьте свойство Terminated).Если вы обнаружите, что потоку было предложено завершить работу, просто выйдите из цикла и выйдите из Execute.

...