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

Какой правильный способ подождать Thread.finalization и поддерживать отзывчивость моего приложения

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

  while WaitForSingleObject(MyThread.Handle, 0) = WAIT_TIMEOUT do
    Application.ProcessMessages;

  ShowMessage('i am done');
4b9b3361

Ответ 1

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

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

Аналогично, вместо того, чтобы ваш пользовательский интерфейс наблюдал за потоком, передайте отчет о потоке в пользовательский интерфейс. Один из способов сделать это - использовать поток PostMessage для отправки настраиваемого сообщения в форму, которая запустила его после ее завершения, и поместить обработчик сообщения в форму для ответа на него.

Ответ 2

Класс VCL TThread имеет свой собственный метод WaitFor(), который внутренне выдает основную очередь сообщений при вызове в контексте основного потока:

MyThread.WaitFor; 
ShowMessage('i am done'); 

Ответ 3

Он выглядит правильно (если это правильно, значит, он выполняет эту работу). То, что я бы изменил, - это подождать немного больше времени (50 мс выглядит хорошо, чтобы поддерживать отзывчивость приложения), не потребляя процессор.

while WaitForSingleObject(MyThread.Handle, 50) = WAIT_TIMEOUT do
  Application.ProcessMessages;
ShowMessage('i am done');

Конечно, есть другие способы сделать это... <joke> но я обычно применяю один из основных технических принципов:

, если он работает, не трогайте его! </joke>

Ответ 4

Я согласен с замечанием Мейсона Уилера, основной поток лучше всего выполнять свою работу, но я бы предложил использовать событие OnTerminate в потоке. Это больше "Delphi natural", а внутренняя логика - бит PostMessage. Поскольку TThread не является компонентом, вы не можете его просмотреть в инспекторе объектов и должны сами писать и присоединять обработчик событий. Он вызывается (в основном потоке!) После завершения/завершения потока.

Ответ 5

Пока все выглядит хорошо, например jachguate, я бы использовал большее значение тайм-аута, чем 0. Если вы используете WaitForSingleObject(MyThread.Handle, 100), тогда основной поток будет ждать немного дольше, таким образом, потребляя меньше циклов процессора.
Однако лучшим решением будет использование сообщений. Ваше приложение запускает поток, а затем помещает все элементы управления в отключенный режим. Затем поток выполняет и когда он заканчивается, используйте SendMessage или PostMessage в главное окно, чтобы уведомить его о том, что поток выполняется снова. Тогда ваше приложение будет просто включать все элементы управления (и все остальное) снова. У этого есть преимущество, что вы сохраняете "естественный" messageloop для приложения вживую, вместо того, чтобы запускать свой собственный messageloop с этим решением. К сожалению, у метода сообщений есть один недостаток: если поток падает, тогда ни одно сообщение не будет отправлен обратно, поэтому план резервного копирования будет практичным. Например, добавив таймер в свою основную форму, которая проверяет каждую секунду, если поток все еще жив. Если нет, он также просто активирует форму снова, снова отключив себя.