Я делал что-то подобное раньше, когда было много объектов сокетов, которые нуждались в периодических запусках и таймаутах.Я использовал класс «TimedAction» с событиями «OnStart» и «OnTimeout» (классы сокетов и т. Д., Полученные из этого) и один поток, который обрабатывал все синхронизированные действия.Поток поддерживал список экземпляров TimedAction, упорядоченный по времени тика следующего требуемого действия (дельта-очередь).Объекты TimedAction были добавлены в список путем помещения их в очередь ввода потока.Поток ожидал в этой входной очереди с тайм-аутом (это была Windows, поэтому «WaitForSingleObject» на дескрипторе семафора, который управлял очередью), установленным на счетчик тиков «требуется следующее действие» первого элемента в списке.Если время ожидания очереди истекло, было вызвано соответствующее событие действия первого элемента в списке, и элемент был удален из списка - следующее ожидание очереди будет установлено новым «первым элементом в списке», который будет содержатьновое «время ближайшего действия».Если в очередь поступило новое действие TimedAction, поток рассчитал время его таймаута (GetTickCount + мс интервал от объекта) и вставил его в отсортированный список в правильном месте (да, это иногда означало перемещение большого количества объектоввверх по списку, чтобы освободить место).
События, вызываемые потоком обработчика тайм-аута, не могут предпринимать длительных действий, чтобы предотвратить задержки при обработке других тайм-аутов.Как правило, обработчики событий устанавливают некоторое перечисление состояния, сигнализируют какой-либо объект синхронизации или ставят в очередь TimedAction в какой-либо другой порт ПК или порт завершения ввода-вывода.
Имеет ли это смысл?Он работал нормально, обрабатывая тысячи синхронизированных действий на моем сервере достаточно своевременно и эффективно.
Одним из улучшений, которое я планировал сделать, было использование нескольких списков с ограниченным набором интервалов времени ожидания.В моей системе было только три интервала тайм-аута, поэтому я мог использовать три списка, по одному для каждого интервала.Это будет означать, что списки не будут нуждаться в явной сортировке - новые TimedActions всегда будут идти в конец их списка.Это исключило бы дорогостоящую вставку объектов в середину списка / ов.Я так и не удосужился сделать это, так как мой первый дизайн работал достаточно хорошо, и у меня было множество других ошибок, которые нужно исправить: (
Две вещи:
Остерегайтесь 32-битного ролика тика.
Вам необходим цикл в блоке тайм-аута очереди - в списке могут быть элементы с одинаковым или почти одинаковым числом тиков тайм-аута. Как только тайм-аут очереди наступит, вам нужно удалить его из списка и запустить событиякаждого объекта до тех пор, пока вновь рассчитанное время ожидания не станет> 0. Я не справился с этим. Два объекта с одинаковым числом тактов тайм-аута прибыли в начало списка. Один получил свои события, но счетчик системных тиков перешел ипоэтому расчетное время ожидания для следующего объекта было равно -1: БЕСКОНЕЧНО! Мой сервер перестал работать правильно и в итоге заблокирован: (
Rgds, Martin