Странная проблема в потоках, приложение не выходит - PullRequest
2 голосов
/ 09 июля 2011

ОК. Я пишу компонент Zoom, и я хотел, чтобы он записывался с экрана во вторичном потоке. Вы можете притвориться, что я просто хочу получить TThread в пустом компоненте. Я не писал никаких кодов в ветке, так что это просто бесполезная ветка. Я написал этот код: Thrd := TCaptureThread.Create(False); в основной класс компонента. Затем я написал Thrd.Free в коде уничтожения основного класса. Теперь, когда я закрываю все приложение, хотя оно разрушает все, процесс не завершается полностью. В диспетчере задач Windows показывает, что количество потоков равно 1, но процесс остается. Если я прокомментирую строку создания потока, все станет хорошо, и приложение быстро завершится. Что я буду делать с этим? (

Заранее спасибо

Ответы [ 3 ]

6 голосов
/ 10 июля 2011

При вызове Thrd.Free запускается следующий код из TThread.Destroy:

Terminate;
if FCreateSuspended then
  Resume;
WaitFor;

Вызов Free для потока, таким образом, завершит поток синхронно.

Я предполагаю, что звонок на WaitFor никогда не возвращается. Возможно TCaptureThread.Execute не проверяет Terminated и завершает работу. Возможно, TCaptureThread ожидает в главном потоке и ожидание тупика в потоке.

Довольно сложно сделать что-либо кроме угадывания, основываясь на вашем вопросе, но я бы хотел проверить, проходит ли ваш код вызов WaitFor при уничтожении Thrd. Включите отладку DCU, установите точку останова при вызове на WaitFor и убедитесь сами.

0 голосов
/ 10 июля 2011

Напишите свою тему следующим образом:

type
  TCaptureThread = class(TThread)
  private
    //
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: False);
  end;

implementation

constructor TCaptureThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  // Set FreeOnTerminate to True
  FreeOnTerminate := True;
end;

procedure TCaptureThread.Execute;
begin
  // Write the Execute method here...
  // And don't forget to synchronise with the form
end;

end.

В форме создайте экземпляр вашей темы

Thrd := TCaptureThread.Create(False);

Выполните ее

Thrd.Execute;

И завершите свою тему

Thrd.Terminate;

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

0 голосов
/ 09 июля 2011

Это может быть ОЧЕНЬ много ... Из метода Execute вашего потока, никогда не выходящего в тупик.

Первое, что вы должны сделать, чтобы попытаться диагностировать, - запустить приложение под Delphi.Затем, поскольку вы говорите, что при закрытии приложения оно зависает, вы закрываете приложение.Теперь, когда ваше приложение зависло, вы приостанавливаете его и проверяете панель отладки Thread.Там нажмите на каждый поток, чтобы проверить их callstack.Это должно дать лучшее представление о том, почему он зависает, и какой именно поток зависает.

...