|
![]() |
#1 |
Участник
|
бедняжка
добавьте X++: //mazzy 13.12.2019: по образцу getTotal() public int64 getCount(int _idx = 1) { if (oprProgress) return oprProgress.getCount_RU(_idx); else if (oprProgressEmbedded ) return oprProgressEmbedded.getCount_RU(_idx); else if ( oprProgressServer ) return oprProgressServer.getCount(_idx); else return 0; } Цитата:
Сообщение от oleggy
![]() Нумерация у меня идет с нуля.
Перед первым выполнением progress.incCount() значение progress.oprProgress.lapProgress равно 0. Как вы видете после запуска джоба я вижу только три изменения окна прогресс бара. ТРИ. Но если я раскомменчу progress.update(true) отображает корректно ЧЕТЫРЕ окна. Цитата:
Заглянул внутрь. Вспомнил. Заодно вспомнил про тему (Не)перерисовка окна клиента AX 2009 при длительных операциях - вариант решения Поностальгировал. ![]() Вернемся к вопросам. Прогресс-бар - это GUI-форма. Обновление GUI-формы - дело относительно не быстрое. Даже перерисовка консольного прогресс бара занимает время. Нормальные прогресс-бары не отрисовывают КАЖДОЕ изменение прогресса, а обновляют по таймеру, чтобы отрисовка не выполнялась дольше, чем полезная работа. Вот и в Аксапте у метода update есть параметр force: если сказать force=true, то update перерисует форму в обязательном порядке если сказать force=false, то update будет перерисовывать только когда пройдет некоторое время с предыдущей отрисовки. поначалу updateInterval равен трем попугаям для сервера и одному попугаю для клиента. по ходу пьесы, progressBar пытается отрегулировать updateInterval так, чтобы он был больше, чем время перерисовки окна. а также пытается показать себя сильно умным ГЛАВНОЕ: метод update(false) НЕ перерисовывает окно при каждом изменении. теперь собственно что происходит: 1. методы setText() и incCount() унутре себя вызывают update(false) следовательно возможна ситуация, когда на первом методе окно будет перерисовно, а на втором - не будет. так и получается рассогласованное изображение окна. но вполне согласованое состояние внутри. 2. когда вы явно вызываете update(true), то окно будет принудительно перерисовано. И каким бы оно ни было нарисовано в предыдущих строках, здесь оно будет нарисовано в согласованном состоянии. 3. попробуйте тест на очень много значений с принудительной отрисовкой и с отрисовкой по умолчанию. замерьте время выполнения. скорее всего вы удивитесь как много времени уходит на отрисовку прогрессБара. мало того, и на обслуживание этой счетчиков тоже тратится время и дополнительно напрягается сборщик мусора. на некоторых проектах даже запрещают использовать прогресс-бар совсем (не рекомендую). 4. что делать: не ориентироваться на точные значения прогресс-бара. выводить текст для того, чтобы примерно представлять где мы находимся (даты обрабатываемых проводок, код товаров в алфавитном порядке и тп) увеличивать updateInterval (рекомендую 5-10 секунд) 5. что можно улучшить: в стандартной аксапте катастрофически не хватает метода, который меняет одновременно и текст, и счетчик. такой метод обычно и добавляют на проектах. Последний раз редактировалось mazzy; 02.10.2020 в 20:25. |
|
|
За это сообщение автора поблагодарили: sukhanchik (10), oleggy (1). |
![]() |
#2 |
Участник
|
Цитата:
Сообщение от mazzy
![]() добавьте
X++: //mazzy 13.12.2019: по образцу getTotal() public int64 getCount(int _idx = 1) { if (oprProgress) return oprProgress.getCount_RU(_idx); else if (oprProgressEmbedded ) return oprProgressEmbedded.getCount_RU(_idx); else if ( oprProgressServer ) return oprProgressServer.getCount(_idx); else return 0; } X++: public int64 getCount(int _idx = 1) { if (oprProgress) return oprProgress.getCount_RU(_idx); else if (oprProgressEmbedded ) return oprProgressEmbedded.getCount_RU(_idx); else return 0; } Я прав? Или для сервера такой функционал тоже нужен - getCount. |
|
![]() |
#3 |
Участник
|
Изменил код с учетом добавленного метода getCount и стало по другому (!):
X++: { Counter currRow; Counter strFrom = 1, strTo = 4; RunbaseProgress progress = new RunbaseProgress(); #AviFiles void progressUpdate() { str percent = strFmt("%1%", decRound((progress.getCount() / progress.getTotal()) * 100, 2)); progress.setText(strfmt("@SYS66083", progress.getCount(), progress.getTotal(), percent)); progress.incCount(); } ; progress.setCaption("Импорт"); progress.setAnimation(#AviUpdate); progress.setTotal(strTo - strFrom + 1); startLengthyOperation(); for (currRow = strFrom; currRow <= strTo; currRow++) { progressUpdate(); sleep(2000); } endLengthyOperation(); } С этим кодом теперь хотя бы показывает корректно полоску прогресс бара: Т.е. 1 - 25%, 2 - 50%, 3 - 75%. 4 шаг не показывает. Похоже тут ничего поделать нельзя. Последний раз редактировалось oleggy; 03.10.2020 в 09:21. |
|
![]() |
#4 |
Участник
|
Цитата:
Если не получается написать метод который вам посоветовал mazzy в пункте 5, то вам проще что-нить убрать - или setText или полоску движка. Я, в случае если хочу в прогрессе уведомить о начале этапа многоэтапной обработки(ну предположим обработка по месяцам) - не стесняюсь, пишу update(true). Если у вас такой же случай, то тоже пишите. А если итераций сотни+, то никто не заметить в движке возможную мелкую несогласованность) |
|
![]() |
#5 |
Участник
|
Цитата:
Сообщение от mazzy
![]() добавьте
X++: //mazzy 13.12.2019: по образцу getTotal() public int64 getCount(int _idx = 1) { if (oprProgress) return oprProgress.getCount_RU(_idx); else if (oprProgressEmbedded ) return oprProgressEmbedded.getCount_RU(_idx); else if ( oprProgressServer ) return oprProgressServer.getCount(_idx); else return 0; } Он тоже самописный. Мне интересно. |
|
![]() |
#6 |
Участник
|
Цитата:
(и вообще считаю, что префиксы-суффиксы - зло. раз, два) код метода SysOperationProgressServer.getCount X++: public int64 getCount(int _idx = 1) { if ( Bypass ) return 0; select ProgressTotal from progress where progress.RecId == progressRecIds[_idx]; return progress.ProgressCount; } в серверном прогресс-баре счетчик записывается в таблицу, которая является общей для всех процессов. и обновление SysProgress параллельными процессами в легкую может стать бутылочным горлышком на сервере. выше я говорил, что некоторые на проектах запрещают использовать ProgressBar вообще. конечно же не для того, чтобы усложить жизнь пользователей ![]() а именно из-за того, что натыкаются на это бутылочное горлышко. в основном проблема возникает, когда программист отлаживает RunBaseBatch на клиенте с прогрессбаром, а потом этот же класс безо всяких модификаций начинает выполняться в пакетнике. есть разные подходы для решения проблемы с прогресс-баром на сервере. что-то сделано и в Аксапте - обратите внимание, как забавно работает процент выполненных работ в пакетных заданиях Цитата:
просто окно прогресса закрывается раньше, чем пользователь успевает заметить. Хинт в том, что винда тоже отрисовывает окошки не сразу. Там тоже свой delay есть. Цитата:
Цитата:
Сообщение от Perc
![]() Я, в случае если хочу в прогрессе уведомить о начале этапа многоэтапной обработки(ну предположим обработка по месяцам) - не стесняюсь, пишу update(true). Если у вас такой же случай, то тоже пишите. А если итераций сотни+, то никто не заметить в движке возможную мелкую несогласованность)
см. форму Tutorial_Progress Цитата:
чтобы сделать его самостоятельно, посмотрите на серверный setCount ![]() |
|
![]() |
#7 |
Участник
|
Цитата:
Сообщение от mazzy
![]() Цитата:
Сообщение от oleggy
Изменил код с учетом добавленного метода getCount и стало по другому (!): ... 4 шаг не показывает. Похоже тут ничего поделать нельзя. просто окно прогресса закрывается раньше, чем пользователь успевает заметить. Цитата:
Если у вас не получается как в пункте 5 и другие варианты не устраивают, то сделайте как в пункте 5)) |
|
![]() |
#8 |
Участник
|
Цитата:
Но ваше восприятие тоже возможно. наверное, точно было выразиться так: или добавить метод, который не обращаясь к методам incCount, setCount, setText, обновляет и счетчик, и текст. после чего вызывает update один раз. |
|
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|