Один из способов решения этой проблемы - использовать SortedList
ожидающих событий (отсортированных по дате их истечения) и использовать таймер, который срабатывает достаточно часто, чтобы удовлетворить временные интервалы, вы хотите работать (например, здесь может хватить одного раза в 250 мс).
Каждый раз, когда срабатывает (одиночный) таймер, он продолжает проверять начало списка, и если элемент на фронте имеет дату истечения срока в прошлом, то мы снимаем с охраны элемент и организуем его запуск (независимо от того, выполняете ли вы запускать события в самом потоке таймера или, например, запускать новые Task
s для их выполнения, зависит от степени того, должны ли события происходить параллельно и сколько времени занимает обработка событий).
Обычно каждый объект события имеет своего рода Action
, встроенный в его структуру, так что этот код диспетчеризации может быть достаточно простым. Повторяющиеся события могут ставить в очередь их «следующее» выполнение как часть их собственных действий, или вы можете выбрать выполнение этой другой формы действия потоком таймера. (Эта вторая модель имеет тенденцию работать лучше, если вы выполняете параллельное выполнение, поскольку только очередь таймера взаимодействует с очередью событий, поэтому блокировка не требуется).
Наконец, как вы запускаете вещи чаще? Полностью отключите таймер и просто извлекайте элементы из очереди непрерывно, игнорируя их сроки выполнения.