From 99ded566559941b8a51cbf8a9b3ee1e35b9510e6 Mon Sep 17 00:00:00 2001 From: Daniel-I-Am Date: Thu, 4 Jun 2020 17:51:21 +0200 Subject: [PATCH] Add Timer service --- ChaosBot/Services/Timer.cs | 117 +++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 ChaosBot/Services/Timer.cs diff --git a/ChaosBot/Services/Timer.cs b/ChaosBot/Services/Timer.cs new file mode 100644 index 0000000..2300a17 --- /dev/null +++ b/ChaosBot/Services/Timer.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace ChaosBot.Services +{ + public static class Timer + { + private static Dictionary _timers = new Dictionary(); + + private static int _nextTimerIndex = 0; + private static int NextTimerIndex + { + get + { + _nextTimerIndex++; + return _nextTimerIndex; + } + } + + public static int RunAt(Action toRun, DateTime deadlineTime) + { + DateTime current = DateTime.Now; + TimeSpan timeToGo = deadlineTime - current; + if (timeToGo < TimeSpan.Zero) + { + return -1; //time already passed + } + + int timerIndex = NextTimerIndex; + _timers.Add(timerIndex, new System.Threading.Timer(x => + { + toRun(); + _timers.Remove(timerIndex); + }, null, timeToGo, Timeout.InfiniteTimeSpan)); + + return timerIndex; + } + + public static int RunIn(Action toRun, TimeSpan dueTime) + { + DateTime current = DateTime.Now; + if (dueTime < TimeSpan.Zero) + { + return -1; //time already passed + } + + int timerIndex = NextTimerIndex; + _timers.Add(timerIndex, new System.Threading.Timer(x => + { + toRun(); + _timers.Remove(timerIndex); + }, null, dueTime, Timeout.InfiniteTimeSpan)); + + return timerIndex; + } + + public static int RunTimer(Action toRun, TimeSpan interval) + { + return RunTimer(toRun, interval, TimeSpan.Zero); + } + + public static int RunTimer(Action toRun, TimeSpan interval, TimeSpan offset) + { + DateTime current = DateTime.Now; + if (offset < TimeSpan.Zero) + { + return -1; //time already passed + } + + int timerIndex = NextTimerIndex; + + void Callback() + { + toRun(); + + if (_timers.ContainsKey(timerIndex)) + _timers.Remove(timerIndex); + _timers.Add(timerIndex, new System.Threading.Timer(x => { Callback(); }, null, interval, Timeout.InfiniteTimeSpan)); + } + + if (offset > TimeSpan.Zero) + { + _timers.Add(timerIndex, new System.Threading.Timer(x => { Callback(); }, null, offset, Timeout.InfiniteTimeSpan)); + } + else + { + Callback(); + } + + return timerIndex; + } + + public static void CancelTimer(int id) + { + if (id < 0) return; + + if (!_timers.ContainsKey(id)) return; + + _timers.GetValueOrDefault(id)?.Dispose(); + + if (_timers.ContainsKey(id)) + _timers.Remove(id); + } + + public static void Join(int id) + { + if (id < 0) return; + + while (_timers.ContainsKey(id)) + { + Thread.Sleep(500); + } + } + } +} \ No newline at end of file