AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.10.2020, 12:45   #1  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,343 / 3563 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Perc Посмотреть сообщение
Да нуу. Не может быть.. Если у меня тотал 4, то чтобы проити весь прогресс, я должен всего 3 incCount сделать? Ломаете мне мир) нужна проверка)
Судя по скриншотам - это так. И поэтому собственно "зависание" на 100%-ах
__________________
Возможно сделать все. Вопрос времени
Старый 02.10.2020, 12:56   #2  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Судя по скриншотам - это так. И поэтому собственно "зависание" на 100%-ах
Эти скриншоты могу сравнить с надписями на заборе) Всем верить чтоле?
Я открыл код которых мильён с прогрессом. И там все норм - с ноля начинается. Тотал - 4, и значит надо 4 итерации чтобы заполнить прогресс.
А что случилось у автора темы не понятно.. толи он нам чего-то не договаривает между точек толи... Ну можем сойтись на том, у него то как раз RunbaseProgress начинается с единицы.. кастомизация)

Последний раз редактировалось Perc; 02.10.2020 в 12:59.
Старый 02.10.2020, 14:42   #3  
oleggy is offline
oleggy
Участник
 
282 / 36 (2) +++
Регистрация: 03.12.2019
Адрес: Россия
У вас проблемы с доверием.
По поводу скриншетов - они абсолютно достоверны.
То что я указал точки (...) не для того что бы что то скрыть - там был код который абсолютно не относится и затрудняет восприятие проблемы.

У меня 4 итерации. Начиная с 1 по 4 включительно. Нумерация в цикле с 1 по 4 включительно. Я же код не зря предьявил.
Вопрос почему на первой итерации уже было 50% прогресса?

Последний раз редактировалось oleggy; 02.10.2020 в 14:47.
Старый 02.10.2020, 15:07   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от oleggy Посмотреть сообщение
Вопрос почему на первой итерации уже было 50% прогресса?
вам уже ответили:
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Ответ-то вроде лежит на поверхности. Судя по индикатору (если не исследовать внутренности кода) - внутренний счетчик прогресс-бара начинается с 1 (а если полезть изучать код, то это можно будет увидеть). И первый вызов progress.incCount() увеличивает его до 2 (а это 50% из 4-х).
если так хотите вручную управлять прогрессом, то воспользуйтесь методом progress.setCount()

а чтобы увидеть значение счетчика внутри прогресса - методом progress.getCount_RU()
__________________
полезное на axForum, github, vk, coub.
Старый 02.10.2020, 15:34   #5  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от oleggy Посмотреть сообщение
У меня 4 итерации. Начиная с 1 по 4 включительно. Нумерация в цикле с 1 по 4 включительно. Я же код не зря предьявил.
Вопрос почему на первой итерации уже было 50% прогресса?
Я скопировал ваш код к себе в джоб Акс4. Добавил sleep(1000) и update(true). И картинка была идеальная на клиенте. 1 - 25%, 2 - 50% и тд.
Воспользуйтесь отладчиком, посмотрите.
Старый 02.10.2020, 18:24   #6  
oleggy is offline
oleggy
Участник
 
282 / 36 (2) +++
Регистрация: 03.12.2019
Адрес: Россия
Перевел весь свой код в просто джоб. Что бы предметно дебажить.
X++:
    Counter             countRows, numRows;
    Counter             strFrom = 1, strTo = 4;
    RunbaseProgress     progress = new RunbaseProgress();
    #AviFiles

    void progressUpdate(Counter _curr, Counter _num)
    {
        str percent = strFmt("%1%", decRound((_curr / _num) * 100, 2));

        progress.setText(strfmt("@SYS66083", _curr, _num, percent));
        progress.incCount();
        //progress.update(true);
    }
    ;

    progress.setCaption("Импорт");
    progress.setAnimation(#AviUpdate);

    numRows = strTo - strFrom + 1;
    progress.setTotal(numRows);

    startLengthyOperation();

    for (countRows = 1; countRows <= numRows; countRows++)
    {
        progressUpdate(countRows, numRows);
        sleep(2000);
    }

    endLengthyOperation();
}


Цитата:
Сообщение от mazzy Посмотреть сообщение
вам уже ответили:
а чтобы увидеть значение счетчика внутри прогресса - методом progress.getCount_RU()
К сожалению нет такого метода (DAX2009).
Поэтому смотрел через дебаг. Нумерация у меня идет с нуля.
Перед первым выполнением progress.incCount() значение progress.oprProgress.lapProgress равно 0.
Как вы видете после запуска джоба я вижу только три изменения окна прогресс бара. ТРИ.

Но если я раскомменчу progress.update(true) отображает корректно ЧЕТЫРЕ окна. Четыре итерации.
Т.е. 1 - 25%, 2 - 50%, 3 - 75%, 4 - 100%.

Я почему тему поднял, просто хотелось понять:
1. почему ТАК криво отображается прогресс бар?
2. после какого оператора происходит обновление окна Импорт? Какой метод это делает? Или после какого метода это происходит?
Изображения
   

Последний раз редактировалось oleggy; 02.10.2020 в 19:48.
Старый 02.10.2020, 20:18   #7  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от oleggy Посмотреть сообщение
2. после какого оператора происходит обновление окна Импорт? Какой метод это делает? Или после какого метода это происходит?
Очень забавно получилось) перевернули местами incCount и setText и картинка перевернулась)
Видимо необходимость в перерисовке окна вычисляется каким то алгоритмом инициируемым при вызове любой из этих функций. От чего этот момент зависит точно - надо дотошно код смотреть. Но фокус получился в том что перерисовка произошла после первой функции в итерации. А на вызове второй алгоритм сказал - к черту, только что обновляли.
Как сделать чтобы текст и движок корректно синхронизировались даже сходу не скажу. Update(true) в общем случае не рекомендуется, если случай большого количества мелких итерации.
Старый 02.10.2020, 20:22   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от oleggy Посмотреть сообщение
Уже весь извелся. Одни маты остались.
бедняжка

Цитата:
Сообщение от oleggy Посмотреть сообщение
К сожалению нет такого метода (DAX2009).
добавьте
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 Посмотреть сообщение
Поэтому смотрел через дебаг.
Серьезно? Не, это не спортивно.

Цитата:
Сообщение от oleggy Посмотреть сообщение
Нумерация у меня идет с нуля.
Перед первым выполнением progress.incCount() значение progress.oprProgress.lapProgress равно 0.
Как вы видете после запуска джоба я вижу только три изменения окна прогресс бара. ТРИ.

Но если я раскомменчу progress.update(true) отображает корректно ЧЕТЫРЕ окна.
как у меня на скриншотах ниже. так?
Нажмите на изображение для увеличения
Название: 2.PNG
Просмотров: 42
Размер:	31.8 Кб
ID:	12957
Нажмите на изображение для увеличения
Название: 22.PNG
Просмотров: 47
Размер:	39.2 Кб
ID:	12958

Цитата:
Сообщение от oleggy Посмотреть сообщение
Я почему тему поднял, просто хотелось понять:
1. почему ТАК криво отображается прогресс бар?
2. после какого оператора происходит обновление окна Импорт? Какой метод это делает? Или после какого метода это происходит?
Хорошие вопросы. И хорошая настойчивость. Спасибо.

Заглянул внутрь. Вспомнил.
Заодно вспомнил про тему (Не)перерисовка окна клиента AX 2009 при длительных операциях - вариант решения
Поностальгировал.

Вернемся к вопросам.

Прогресс-бар - это GUI-форма.
Обновление GUI-формы - дело относительно не быстрое.
Даже перерисовка консольного прогресс бара занимает время.
Нормальные прогресс-бары не отрисовывают КАЖДОЕ изменение прогресса, а обновляют по таймеру, чтобы отрисовка не выполнялась дольше, чем полезная работа.

Вот и в Аксапте у метода update есть параметр force:
если сказать force=true, то update перерисует форму в обязательном порядке
если сказать force=false, то update будет перерисовывать только когда пройдет некоторое время с предыдущей отрисовки.

Нажмите на изображение для увеличения
Название: 1.PNG
Просмотров: 50
Размер:	45.7 Кб
ID:	12960

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

Нажмите на изображение для увеличения
Название: 3.PNG
Просмотров: 53
Размер:	25.7 Кб
ID:	12962
Нажмите на изображение для увеличения
Название: 5.PNG
Просмотров: 48
Размер:	35.3 Кб
ID:	12961

ГЛАВНОЕ: метод update(false) НЕ перерисовывает окно при каждом изменении.

теперь собственно что происходит:
1.
методы setText() и incCount() унутре себя вызывают update(false)
следовательно возможна ситуация, когда на первом методе окно будет перерисовно, а на втором - не будет.

так и получается рассогласованное изображение окна.
но вполне согласованое состояние внутри.

2.
когда вы явно вызываете update(true), то окно будет принудительно перерисовано. И каким бы оно ни было нарисовано в предыдущих строках, здесь оно будет нарисовано в согласованном состоянии.

3.
попробуйте тест на очень много значений с принудительной отрисовкой и с отрисовкой по умолчанию.
замерьте время выполнения.
скорее всего вы удивитесь как много времени уходит на отрисовку прогрессБара.
мало того, и на обслуживание этой счетчиков тоже тратится время и дополнительно напрягается сборщик мусора.

на некоторых проектах даже запрещают использовать прогресс-бар совсем (не рекомендую).

4.
что делать:
не ориентироваться на точные значения прогресс-бара.
выводить текст для того, чтобы примерно представлять где мы находимся (даты обрабатываемых проводок, код товаров в алфавитном порядке и тп)
увеличивать updateInterval (рекомендую 5-10 секунд)

5.
что можно улучшить:
в стандартной аксапте катастрофически не хватает метода, который меняет одновременно и текст, и счетчик.
такой метод обычно и добавляют на проектах.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 02.10.2020 в 20:25.
За это сообщение автора поблагодарили: sukhanchik (10), oleggy (1).
Старый 03.10.2020, 05:27   #9  
oleggy is offline
oleggy
Участник
 
282 / 36 (2) +++
Регистрация: 03.12.2019
Адрес: Россия
Цитата:
Сообщение от 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;
}
Т.к. oprProgressServer (класс SysOperationProgressServer) не имеет наследника SysOperationProgressBase у которого getCount_RU есть.
Я прав? Или для сервера такой функционал тоже нужен - getCount.
Старый 03.10.2020, 13:56   #10  
oleggy is offline
oleggy
Участник
 
282 / 36 (2) +++
Регистрация: 03.12.2019
Адрес: Россия
Цитата:
Сообщение от 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;
}
Приведите прошу еще код getCount из класса oprProgressServer.
Он тоже самописный. Мне интересно.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
How to make your ProgressBar progress on server Blog bot DAX Blogs 0 27.12.2013 02:15
Некорректное отображение прокрутки в lookup random DAX: Программирование 2 15.04.2013 16:55
mazzy: Комфортный ProgressBar в DAX 2009 Blog bot DAX Blogs 5 04.09.2012 16:36
Отображение связи n:n на форме mazzy DAX: Программирование 22 16.03.2011 16:19
mazzy: Комфортный ProgressBar Blog bot DAX Blogs 12 05.02.2009 19:54
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 19:45.