:: Visual Foxpro, Foxpro for DOS
Как прервать выполнение кода в форме при нажатии на Esc
ZenTigra
Автор

Сообщений: 514
Дата регистрации: 03.12.2004
Есть отчет, выполнение которого происходит очень долго (от 0,5 до 15 минут, в зависимости от установленных параметров)
Временами в спешке нажимаешь [Выполнить], при этом забываешься правильно установить необходимые галочки.
А потом ждешь, и мат...ся, ждешь и ...

Решил сделать прерывание по Esc

Сам код процедуры не хочу выкладывать, он слишком большой, та и не зачем,
Там идет несколько SQL-запросов, потом SCAN ... ENDSCAN
Потом опять sql-запросы, SCAN ... ENDSCAN и т.д.
И так несколько раз...

Попытался использовать KeyPress, но при нажатии на ESC ничего не происходит, программа как будто бы подвисает
Включил SET ESCAPE ON, ON ESCAPE DO... то же самое

Единственное решение, которое сработало, это вставка кода,

IF INKEY()=27
T_messagebox=MESSAGEBOX("Прекратить создание отчета?",32+256+4,"")
IF T_messagebox=6
...
ENDIF
ENDIF

но в отчете около 1500 строк кода, я то попотею, вставлю его в разных местах, но думаю есть все таки стандартное решение...

PS.Забыл уточнить, SQL-запросы осуществляются к родным, фоксовским таблицам.



Исправлено 3 раз(а). Последнее : ZenTigra, 10.07.19 13:05
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
pasha_usue

Сообщений: 3650
Откуда: Е-бург
Дата регистрации: 06.10.2006
SET ESCAPE + DOEVENTS FORCE (эпизодически).
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Надо найти наиболее тормозные точки в коде, и все же проставить эти "IF LASTKEY()...". Код с IF-ом обернуть в функцию, у меня называется NEEDEXIT, SET ESCAPE для этого не нужен
SCAN
IF NEEDEXIT()
EXIT
ENDIF
ENDSCAN

Фоксовый SQL-запрос наоборот, прерывается по SET ESCAPE ON, я его включаю только на момент выполнения запроса, прерывается он своеобразно (там с RETRY получилось)

... сохраняем старое окружение
SET ESCAPE ON && чтобы кнопкой ESCAPE была возможность прервать затянувшуюся выборку
ON ESCAPE DO SQLSELECT_ON_ESCAPE && нештатный обработчик ESCAPE (штатный предлагает Ignore,Suspend,Cancel, кнопки НЕ Ignore приводят к повешению)
... сам запрос...
...восстанавливаем старое окружение
PROCEDURE SQLSELECT_ON_ESCAPE && **********************************************************
IF !D_D("Прервать выборку ?")
RETRY && повторить SELECT
* RETURN
ENDIF
DO BEEPER WITH 1, "Прервано"
RETURN
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Добавлю по UI.

У меня есть ряд длительных процессов.
(В основном это массовая печать)

Так вот, esc не лучший выбор.
Гораздо яснее повесить формочку, с кнопкой "Прервать отчет", или что то там.

Понятно, совершенно не грамотному.
(Ну дополнительно туда вывожу, какую то инфу. Может больше для отладки, но и юзер представляет, ск. еще это безобразие длиться будет)))
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Для такой формочки тем более нужно будет пораспихивать по коду всех этих DOEVENTS и проверок флажка с выходом "если отменили" (естественно это повлияет на скорость работы кода сугубо отрицательно). При этом прервать отдельную команду (в частности один SQL запрос) не получится - а вот SET ESCAPE + кнопка esc таки способны это сделать. Хотя код обработки там таки должен быть не очень простым.
Ну и да, есть большие подозрения что оптимизировав процесс создания отчёта можно его заметно ускорить. 15 минут - это очень уж солидно - это либо реально гигабайты данных (при том, вероятно, и в выходном отчёте тоже "десятки тысяч страниц" получаются), либо слишком много ненужных украшательств - если речь про какой word/excel отчёт.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Igor Korolyov
(естественно это повлияет на скорость работы кода сугубо отрицательно
Много зависит, что такое формируется за 15 мин.
Не думаю что проверка if flag exit, как то реально повлияет на скорость.

Я давно пришел к пониманию, понятный интерфейс, лучше красивого. И esc в этом случае никто не запрещает здесь же.

Поясню где это влепил.
Есть массовая печать доков. За месяц.
ПО то крутится мгновенно, но печать то идет долго.
Потому висит эта форма
в скане опрашиваю флаг, ну и все.

И я ж не настаиваю)))
Но сам бы сделал именно так. Уверен на его
ZenTigra
(от 0,5 до 15 минут, в зависимости от установленных параметров)
это никак не повлияет.
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Если логика построена на пресловутых циклах, то добавление внутрь даже тривиальнейшего IF LASTKEY() уже нормально так повлияет на скорость. А чтобы ещё и на мышку реагировало - без DOEVENTS не обойтись - и это ещё сильнее затормозит "процесс". Можно ли добавить проверку в такие места где оно с одной стороны не миллиард раз будет исполняться, а с другой стороны проверка таки будет хотя бы раз в 10-20 секунд выполнена - ну это уже надо постараться


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> добавление внутрь даже тривиальнейшего IF LASTKEY() уже нормально так повлияет
Не грузи. В нагруженном скане эта фигня не заметна по времени ...
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Taran

Сообщений: 13626
Откуда: Красноярск
Дата регистрации: 16.01.2008
Я вообще считал/считаю что окно с кнопкой не будет работать пока какой-то код выполняется.
Поэтому делал COM-EXE-Сервер, а в нем окно с кнопкой и инфой. Т.е. дополнительный поток.
Клик по кнопке устанавливал в родительском приложении флаг о необходимости остановки.
Т.е. цикл в главном приложении не анализирует ни lastkey ни чего прочего. Никаких doevents force.
Просто цикл и анализ флага.
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Пистец. Давай кода кусочек
youtu.be - какако-какао



Исправлено 1 раз(а). Последнее : of63, 12.07.19 22:29
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
ZenTigra
Автор

Сообщений: 514
Дата регистрации: 03.12.2004
Да почти половина логики построена на пресловутых циклах Scan...Endscan.
Вставлять у все циклы обработку LASTKEY() не хотелось, начал искать самые долго выполняемые участки, и нашел парочку не оптимизированного кода, исправил, и там где было ~10 мин. стало 45-50 сек. А это уже терпимо, и обработка прерывания по Esc отпала сама собой.

И таки да, обработка LASTKEY() в циклах существенно замедляет работу.

Спасибо за помощь.
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> обработка LASTKEY() в циклах существенно замедляет работу.
Если времена обработки более 10 сек, то дополнительный вызов LASTKEY на каждом обороте скана, фора - несущественен
Это проверяется таким образом, после IF LASTKEY вставь LOOP (внутри скана), измерь время выполнения скана, потом убери LOOP, замерь время выполнения, вычти эти временА, проанализируй разницу.
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
> обработка LASTKEY() в циклах существенно замедляет работу.
Если времена обработки более 10 сек, то дополнительный вызов LASTKEY на каждом обороте скана, фора - несущественен
Естественно, если у тебя 10 итераций по 30 секунд, то проверка абсолютно несущественна. А если у тебя 1трлн итераций по 0.000001 секунды, то совсем другое дело


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Ну да, математику еще помним. А как вы прерываете прогу с сишарпах?
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
А зачем её прерывать

Если серьёзно, то в асинхронных сценариях (и в параллельных тоже) применяют специальный механизм CancellationToken. Если очень грубо и очень упрощенно, это как раз и есть "флажок" выставляемый некоторым наружным кодом, и проверяемый внутренним "тяжёлым" вычислительным кодом на регулярной основе. Т.к. асинхронные и параллельные операции как правило выполняются в отдельных потоках (ну, как минимум в отдельном от UI потоке для десктопных приложений), то UI (интерфейс пользователя) не "блокируется/подвисает", и позволяет спокойно нажимать кнопки - ту же кнопку отмены, что выставит флажок, и внутренняя "тяжёлая" работа будет вскоре отменена. Для некоторых особых случаев пускают в ход и "тяжёлую артиллерию" - принудительно убивают "снаружи" зациклившийся, или просто не предусматривающий штатного (мягкого/управляемого) способа "отмены" код - убивая весь поток в котором этот код исполнялся.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Завести поток-контролер выполнения длинного кода... Сам то применял? Очень тяжеловесно.
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Taran

Сообщений: 13626
Откуда: Красноярск
Дата регистрации: 16.01.2008
of63
Пистец. Давай кода кусочек

Ежели еще не пропал интерес...


+++ Добавчик
Там результаты приведены при вставленном пустом ожидании в цикле из ста итераций Sleep(100).
*!* Мои результаты: 10.098, 49.541, 12.362
Ежели эту пустышку заблокировать, то разница ваааще ахтунг.
*!* Если задержку убрать: 0.048, 48.995, 0.153



Исправлено 3 раз(а). Последнее : Taran, 13.07.19 17:18
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Много строк, попробую уловить идею )
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Taran

Сообщений: 13626
Откуда: Красноярск
Дата регистрации: 16.01.2008
of63
Много строк, попробую уловить идею )

Да там половина не имеет смысла к тесту. Подготовка проекта. Просто чтоб архив не паковать положил все в кучу.
Ratings: 0 negative/0 positive
Re: Как прервать выполнение кода в форме при нажатии на Esc
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Завести поток-контролер выполнения длинного кода... Сам то применял? Очень тяжеловесно.
Фреймворк упрощает жизнь - вся нудятина заложена в системном/инфраструктурном коде - в прикладном только дёргай за нужные ниточки. И ничего "тяжёловесного" там не будет. Расходы на обработку UI потока минимальны (ну висит себе форма и висит - изредка перерисовываясь если её двигают или ещё как взаимодействуют - та же нагрузка что и в режиме "простоя" приложения. Расходы на проверку флага - да, это больное место - это надо думать и очень аккуратно расставлять. Чтобы в тот самый миллиардно-трилионный цикл случайно не впихнуть, а если и в него (ну бывает что нет другого выхода), то с очень мощным throttling-ом, ну типа "проверять на каждое стомилионное срабатывание цикла".


------------------
WBR, Igor
Ratings: 0 negative/0 positive


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

On-line: 30 (Гостей: 30)

© 2000-2024 Fox Club 
Яндекс.Метрика