Вопрос № 25358: У меня в проге то место, которое может зависнуть(если юзер введёт "удачные" данные) содержит ну ОЧЕНЬ много вложенных процедур(и многие из них потенциально могут зависнуть из-за условий в while которые вводит юзер). Так вот как сделать, что...
Вопрос № 25.358
У меня в проге то место, которое может зависнуть(если юзер введёт "удачные" данные) содержит ну ОЧЕНЬ много вложенных процедур(и многие из них потенциально могут зависнуть из-за условий в while которые вводит юзер). Так вот как сделать, чтобы пользователь нажал на esc, к примеру, и прога вышла из ВСЕХ процедур. Основная проблема-это то что даже таймер перестаёт работать, а как взять событие я не знаю... а во вторых я слишком ленив чтобы во все циклы вставлять проверку(да и лишнее условие в цикле -
лишние тормоза).
Отвечает: Lector
Здравствуйте, Андрей Владимирович!
Используйте функцию break. Это, так называемое, тихое исключение, которое будет перехвачено в конструкции catch/finally. При срабатывании этого ислючения, в случае если оно небыло перехвачено, сообщение об ошибке не выдаётся. Скорее всего этот метод Вам подойдёт.
А вообще, чтобы не попадать в такие ситуации впредь, советую поизучать рефакторинг.
--------- Хочешь помочь дураку - сам дурак
Ответ отправил: Lector (статус: 2-ой класс)
Отправлен: 26.08.2005, 17:36
Отвечает: Denisss Здравствуйте, Андрей Владимирович!
Используйте потоки (TThread). Потери времени будут минимальными (на создание, запуск потока, получение из него данных и удаление).
Ответ отправил: Denisss (статус: Студент)
Отправлен: 26.08.2005, 17:39
Отвечает: X
Здравствуйте, Андрей Владимирович!
Можно запускать процедуры в отдельном потоке(примеров потоков в рассыке было много), хотя смотря чего в этих процедурах делаеться. Тогда на esc просто останавливать этот поток. Но лучше всё-таки проверять данные, и не в циклах, а сразу после ввода, или хотя-бы предупредить юзера.
Ответ отправил: X (статус: 8-ой класс)
Отправлен: 26.08.2005, 17:53
Отвечает: Полищук Владислав Игоревич
Здравствуйте, Андрей Владимирович!
1. Стоит все -таки, по возможности, проверять заранее (до цикла) данные введенные пользователем, чтобы они не приводили к зависанию.
2. В теле циклов нужно проставить вызов процедуры Application.ProcessMessage,
которая принудительно обрабатывает сообщения.
3. Далее, по обработке нажатия Escape, нужно либо генерить исключение и ловить его на верхнем уровне, либо взводить какой-нибудь флаг, по которому циклы будут досрочно завершаться
--------- Чтобы вчера не случилось, радуйся новому дню
Ответ отправил: Полищук Владислав Игоревич (статус: 1-ый класс)
Отправлен: 26.08.2005, 18:28 Оценка за ответ: 5 Комментарий оценки: я всего лишь не знал процедуры: Application.ProcessMessage, а "проверять заранее (до цикла) данные, введенные пользователем" – никак низя условий как минимум 4 (доходит до 10) и как они друг на друга влияют - это ... PS: я поставил 5, что бы такой хороший человек не задерживался в 1-ом классе.
Отвечает: sir henry
Здравствуйте, Андрей Владимирович!
Лень - двигатель эволюции. :)
А Вы пойдите по другому пути - поставьте проверку на вводимые юзером данные, тогда съэкономите свои силы на написание исключений во всех процедурах. :)
А так, чтобы один эскейп выходил из всех процедур, это по кол-ву кода равнозначно тому, чего Вы ленитесь делать. :)
Ответ отправил: sir henry (статус: Профессор)
Отправлен: 26.08.2005, 19:19
Отвечает: Delphin
Здравствуйте, Андрей Владимирович!
Введи переменную допустим UserAbort: Boolean;
И в каждый цикл напиши
while ( not UserAbort ) and ( { Твоё условие } ) do
begin
// Что ты там делаеш
end;
По обработчику клавиш напиши
If Key = vk_Escape then UserAbort := True;
-----------------------------------------
Перед циклом не забудь написать UserAbort := False; // Чтобы из цикла само не выходило.
--------- Обращаться в ICQ: 77778851 или E-Mail: delphinster@gmail.com
Ответ отправил: Delphin (статус: 8-ой класс)
Отправлен: 26.08.2005, 20:48
Отвечает: Силантьев Евгений Александрович
Здравствуйте, Андрей Владимирович!
В приложение пример того, что Вы просили.
Все ваши циклы надо привести к виду:
while условие do
begin
if error then exit
else
begin
// тело цикла
end;
end;
Если честно, с моей точки зрения, более надежней проверять значения при вводе. Но выбор все равно за Вами. Успехов!!!
Приложение:
--------- The world is mine! :)
Ответ отправил: Силантьев Евгений Александрович (статус: 3-ий класс)
Отправлен: 26.08.2005, 23:51 Оценка за ответ: 4 Комментарий оценки: спасибо, всё супер токо я запустил написал 1 нажал батон , нажал esc и нажал паузу .... нажал F8 ... цикл продолжался....
Отвечает: Ерёмин Андрей Здравствуйте, Андрей Владимирович!
На самом деле от нескольких условий никаких тормозов не будет. Объявите глобальную переменную (например NeedExit: Boolean = False;). В цикле поставьте проверку на значение этой переменной:
Application.ProcessMessages;
If NeedExit Then Exit;
Однако не следует ставить данное условие в каждый из циклов (особенно, если у вас они вложены друг в друга). Поставьте в тот цикл, что выполняется примерно через секунду, т.е. не слишком часто. Когда пользователь нажмёт Esc, то действие завершится не моментально, а через небольшой промежуток времени.
--------- Мышка побежала, xвостиком махнула - cервер упал...
Ответ отправил: Ерёмин Андрей (статус: Практикант)
Отправлен: 27.08.2005, 12:51 Оценка за ответ: 4 Комментарий оценки: спасибо, но я писал: "содержит ну ОЧЕНЬ много вложенных процедур" , а Exit - это выход токо из одной процеДуры