chaosbot/ChaosBot/Services/Timer.cs
2020-06-04 19:13:00 +02:00

117 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace ChaosBot.Services
{
public static class Timer
{
private static Dictionary<int, System.Threading.Timer> _timers = new Dictionary<int, System.Threading.Timer>();
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);
}
}
}
}