Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Исключить частое оповещение GUI об изменениях


Автор: Ruzzz 26.11.2009, 18:41
Есть данные. Нужно чтобы на при их изменении обновлялось GUI. При этом данные изменяется по внешнему для приложения событию. Может быть как сотни изменений в секунду, так и одно в час. Задача при частом изменении, не оповещать каждый раз GUI, чтобы увеличить скорость приложения (не тратить ресурсы на обновление GUI).

Делаю с использованием таймера. При очередном изменении, запускаю таймер с интервалом 1 секунда, если же таймер уже запущен, то "обнуляю" его. Таймер дает команду GUI обновится и отключает себя. Таким образом GUI обновляется только через секунду после последнего изменения. Но. Здесь также тратиться ресурс, при каждом изменении данных, на работу с таймером.

Можно ли это делать эффективнее?

Автор: quarz 27.11.2009, 15:55
Попробуй первый способ, когда гуи обновляется по внешнему событию, но с доработками. При каждой перерисовке делай проверку, сколько прошло времени с последнего обновления:

Код

if ((now() - t) < 1000) return;
t = now();
... обновление гуи


Добавлено через 14 минут и 3 секунды
мой вариант может провалиться, если два изменения произойдут быстро, а третье через большой промежуток времени. Тогда гуи обновится при 1м и 3м изменении, и второго мы так и не увидим.

Автор: Earnest 27.11.2009, 19:11
Смотря на чем пишешь, и какие есть механизмы в твоей среде. Один из самых "экономных" вариантов - это инвалидация + холостой цикл. Т.е. при получение сообщения об изменении ставим флаг "все нужно обновить", но больше ничего не делаем. В холостом цикле проверяем этот флаг и, если надо, обновляем ГУИ и сбрасываем флаг. Смысл холостого цикла в том, что он один (или не один) раз срабатывает после каждого "освобождения" системы. Скажем, после очистки очереди вообщений (в Виндоус).  Если в среде нет холостого цикла, тогда его заменяет таймер, но тоже с установкой флага. Т.е. по таймеры проверяем флаг и обновляемся только при необходимости. Кстати, таймер много ресурсов не жрет, он обычно очень низкоприоритетный.

Автор: Ruzzz 27.11.2009, 19:45
Earnest,  пишу под винду, но хотелось бы универсальное решение, есть желание портировать прогу.

Про «холостой цикл» на базе таймера я думал, но так и не смог придумать нормальное решение. Далее я напишу подробно. Кроме таймера наверное только событие «отсутствие сообщений»? Или что вы имеете в виду? OnIdle в MFC или тоже в Delphi VCL? Но очередь вообщем то у меня и так при операциях не загрязняется smile да и охота контролировать процесс обновления. 

Про таймер. Думал сделать так: Таймер работает с частотой 1 сек. и проверяет флаг, если установлен то сбрасывает флаг и обновляет GUI, при любом изменении флаг устанавливается. Но у меня может быть ситуация когда в течении нескольких десятков секунд идет обработка данных, не хотелось бы чтобы в это время было обновление GUI.

Автор: Earnest 27.11.2009, 20:24
Цитата(Ruzzz @  27.11.2009,  20:45 Найти цитируемый пост)
Кроме таймера наверное только событие «отсутствие сообщений»? Или что вы имеете в виду? OnIdle в MFC или тоже в Delphi VCL?

Типа того. Очередь - один из вариантов; просто как пример занятости программы.

Цитата(Ruzzz @  27.11.2009,  20:45 Найти цитируемый пост)
 Но у меня может быть ситуация когда в течении нескольких десятков секунд идет обработка данных, не хотелось бы чтобы в это время было обновление GUI.

Тогда еще один флаг "я занят, просьба не лезть с глупостями)"
Или, как вариант, вызов холостого цикла при завершении обработки. Холостой проход можно реализовать как угодно, хоть сообщением, хоть просто функцией - как удобнее.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)