Закрытие окна на остановке потока - PullRequest
2 голосов
/ 10 декабря 2010

У меня вопрос по темам и элементам управления. Я сделал синхронизирующий модальный диалог. Есть три индикатора и пара подписей. Если приложение открывается в первый раз, оно открывает диалог синхронизации и выполняет обновление. В диалоге Show () я создаю три разных потока. Каждый поток контролирует загрузку данных, анализ XML и вставку базы данных. А затем показывает прогресс на прогрессбар. Все описано, работает нормально.

Теперь проблема - я хочу закрыть это диалоговое окно автоматически, когда все элементы загружены, проанализированы и вставлены в базу данных. Я попытался проверить, равно ли progressbar.position равным progressbar.max, и попытался проверить, не завершены ли потоки. Если я иду по пути выполнения, диалоговое окно закрывается слишком рано, и один индикатор не заканчивается полностью. Если я иду по пути проверки потока, то прогресс-бары останавливаются в середине процесса, и все.

Может быть, вы сделали это и скажите Delphi n00b, как лучше всего это сделать.

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

Ответы [ 3 ]

5 голосов
/ 10 декабря 2010

Для этой простой вещи вы можете использовать событие потока OnTerminate (которое выполняется в контексте основного потока) просто для уменьшения переменной "счетчик потоков", инициализированной в 3 в момент создания потока.

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

begin
  //..thread creation, stuff
  FThreadCount := 3;
  DownloadThread.OnTerminate := DecThreadCount;
  ParseThread.OnTerminate := DecThreadCount;
  InsertThread.OnTerminate := DecThreadCount;
  //resume threads and other stuff
end;

procedure TForm1.DecThreadCount(Sender: TObject);
begin
  Dec(FThreadCount);
  if FThreadCount = 0 then
    Close;
end;
2 голосов
/ 10 декабря 2010

Вы используете Windows Vista или Windows 7? Microsoft изменила способ работы индикаторов выполнения в Vista, поэтому вместо того, чтобы сразу же переходить к указанной позиции, она постепенно скользит к ней. Это означает, что ваш прогресс на самом деле может быть завершен, но панель не будет указывать это в течение еще одной секунды или около того, поэтому похоже, что диалоговое окно закрыто до того, как вы закончите, особенно если на панели есть небольшое количество шагов прогресса.

Это немного уродливо, но вы можете обойти это, используя вспомогательную функцию, которая делает что-то вроде этого:

procedure UpdateProgressBar(bar: TProgressBar);
begin
  bar.StepIt;
  bar.Max := bar.Max + 1;
  bar.Max := bar.Max - 1;
end;

Это обеспечит немедленный переход в правильное положение.

РЕДАКТИРОВАТЬ: Подробности в Как заставить TProgressBar перестать отставать?

1 голос
/ 10 декабря 2010

Я бы заставил ваши темы публиковать сообщения обратно в диалог после их завершения. После получения всех трех сообщений вы можете закрыть диалоговое окно.

...