Поддержание всех этих таймеров кажется действительно запутанным.
Почему бы просто не вести список случаев, когда вы хотите, чтобы событие произошло? И сделайте событие делегатом.
ConcurrentDictionary<DateTime,Action> events = new ConcurrentDictionary<DateTime,Action>();
Когда кто-то что-то щелкает,
events.TryAdd(DateTime.Now.AddSeconds(30), () => HandleEvent(whatever, you, want));
В обработчике убедитесь, что нет более позднего события.
void HandleEvent()
{
if (events.Keys.Any( dateKey => dateKey > DateTime.Now )) return;
DoStuff();
}
Теперь вам просто нужен способ, чтобы события происходили.
timer.Elapsed += (s,e) => {
var list = events.Where( item => item.Key <= DateTime.Now ).ToList();
foreach (var item in list)
{
item.Value.Invoke();
events.TryRemove(item);
}
};