| 
| 
 | Вопрос # 811/ вопрос решён / | 
 |  Добрый вечер, всем, кому не спится!
 Уважаемые Експерты, подскажите как организовать контроль за процессом. Если запустил программу на расчет, достаточно длительный, а хочется прервать, выйти на исходный уровень, или вообще прекратить работу приложения?
 Заранее благодарен всем, кто откликнется.
 
|  |   Вопрос задал: Драганов Василий Михайлович (статус: Посетитель)Вопрос отправлен: 1 августа 2007, 00:45
 Состояние вопроса: решён, ответов: 3.
 |  Ответ #1. Отвечает эксперт: min@y™ Способ №1 "Ламерский" :))Допустим, есть некий цикл, в котором выполняются длительные вычисления. Чтобы программа не подвисала и отвечала на сообщения Windows, предусмотрен метод Application.ProcessMessages(), который нужно периодически вызывать из тела цикла. Примерчик:
 
 
  
var
  Cancelled: Boolean; // Глобальная переменная
 
procedure Process;
const
  Count = 1000000;
var
  Index, Progress: Integer;
begin
  ProgressBar.Position:= 0;
  Cancelled:= false;
 
  for Index:= 0 to Count - 1 do
    begin
      // ...
      // Что-то вычисляется здесь
      // ...
 
      Progress:= Round(100 * (Index + 1) / Count); // Прогресс выполнения
 
      if Progress >< ProgressBar.Position
        then begin
               ProgressBar.Position:= Progress;
               Application.ProcessMessages;  // Обновление информации
             end;
 
      if Cancelled
        then break; // Принудительный выход из цикла
    end;
end;Как видно из примера, помимо контроля над процессом вычислений выдаётся и прогресс выполнения в процентах.
 
 Способ №2 "Продвинутый".
 Использование отдельного потока (Thread) и его метода Sinchronize() для синхронизации с основным потоком. Могу написать пример, если нужно (сейчас времени нет, работать надо), однако в сети полно статей с примерами, нужно только погуглить немного.
 
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 1 августа 2007, 08:48
 Оценка за ответ: 5
 Комментарий к оценке: Ответом удовлетворен на 100%, потому оценка "5". Спасибо за помощь эксперту min@y™. |  Ответ #2. Отвечает эксперт: Вадим К Здравствуйте, Драганов Василий Михайлович!Если программа расчёта не ваша, то тут достаточно сложно что то сделать. Можно конечно подключиться к программе своей как отладчиком, сохранить всю её память и рабочий контекст, а потом восстановить. Но это достаточно накладно.
 
 Если же программа расчётов ваша, то тут наверное самое лучшее - это потоки. В ближайшей рассылке должна быть моя статья о потоках, оттудова можно почерпнуть некоторую информацию. В этом случае при завершении потока основной программой он не сразу "умирает", а имеет возможность сохранить своё состояние.
 
 Если же скорость расчётов принципиально важна, а внешний вид нет, то лучшим решением будет консольное приложение. Оно время от времени должно проверять, не нажата ли заветная клавиша и прерывать расчёт
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 1 августа 2007, 11:52
 Оценка за ответ: 4
 |  Ответ #3. Отвечает эксперт: Помфюк Владимир Степанович Здравствуйте, Драганов Василий Михайлович!Вообще-то самый красивый вариант - это комбинация обеих способов из первого ответа:
 -расчёт производите в отдельном потоке (правда, лично мне, больше нравятся API\'шные функции работы с потоком чем TThread)
 -в нём-же систематически проверяете не пришла ли какая команда от главной программы (завершится, рестартовать - всї что угодно) и если да, то, естественно, выполняете её
 -в главном потоке в цикле проверяете нет ли сообщений от процесса расчёта (нарисовать что-то или просто о том что он уже закончился). Если нет - Application.ProcessMessages, если да - среагировать соответственно.
 
 Мини-форум вопросаВсего сообщений: 0. 31 января 2011, 20:02: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5) Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |