Страницы

Поиск по вопросам

воскресенье, 15 марта 2020 г.

Как ограничить частоту вывода информации при приеме сообщений (сигналов)?

#c_sharp #cpp #алгоритм


Предположим, у нас есть некий источник сообщений. Это может быть что угодно, какой-то
модуль программы, или оборудование, неважно.
Сообщение может приходить и 1 раз в час, а может и 100500 раз в секунду.
В окне программы нужно обновлять информацию по приходу этого сообщения.

При этом очевидно, что обновлять информацию 100500 раз в секунду не имеет никакого
смысла, да и накладно это.
Но в то же время хотелось бы, чтобы в случае редкого прихода сигнала (особенно когда
этот сигнал вызван действиями пользователя, например, если пользователь что-то нажал),
не было видимой задержки при обновлении информации в окне программы (в случае таймера).

Как это можно красиво реализовать. Или ничего кроме простого таймера на 100, 200,
или 1000 ms не придумать? Держать таймер, ради сообщения которое может прийти раз в
час тоже не хочется. 

Грубо говоря, хочется сделать какой-то ограничитель частоты сообщений. При этом,
когда на нас вдруг посыпались 100500 сообщений, а потом прекратились, информация о
ПОСЛЕДНЕМ сообщении обязательно должна быть отображена (пусть и  с задержкой), а не
пропущена.

Контекст: проблема возникла при обновлении информации в окне при приеме одного WINAPI
сообщения, которое отправляется слишком часто, при этом оно может быть спровоцировано
как действиями пользователя, так и программным методом.
    


Ответы

Ответ 1



Вариант ленивый: писать события в очередь, и по таймеру, раз в 100мс например, выводить их в окно. Вариант более хитрый - по приходу события вызывать обработчик и в нем запускать таймер, на те же 100мс например. Далее, если до этого таймер запущен не был, то выводить событие в окно. Если таймер был запущен - не выводить. Как только таймер сработал - вывести последнее событие. Итого получится событийно-таймерное решение. Естественно, если старые события не представляют интереса, то избавиться от очереди и хранить только последнее событие.

Ответ 2



По-моему, самый эффективный и простой вариант выглядит так: 0) Висим на синхронизирующем объекте ядра в ожидании нового события. Т.е. не занимаемся отрисовкой вообще, если нет событий. 1) В момент, когда пришло событие - отрисовать его моментально, и зависнуть на N миллисекунд, а потом снова в пункт 0. Синхронизация Вам всё равно нужна, раз отрисовка событий и новые сообщения не связанные между собой нити выполнения, т.ч. какой-то объект ядра Вы всё равно будете использовать. На нем и висеть.

Комментариев нет:

Отправить комментарий