Skip to content

Instantly share code, notes, and snippets.

@Brian1KB
Created June 22, 2017 16:23
Show Gist options
  • Save Brian1KB/d552b6895e71ca90cd15c4d4f72653cd to your computer and use it in GitHub Desktop.
Save Brian1KB/d552b6895e71ca90cd15c4d4f72653cd to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace MiNET.Utils
{
public class HighPrecisionTimerManager
{
private static readonly ConcurrentDictionary<Thread, List<HighPrecisionTimer>> Managers = new ConcurrentDictionary<Thread, List<HighPrecisionTimer>>();
static HighPrecisionTimerManager()
{
for (var i = 0; i < 32; i++)
{
Thread innerThread = null;
var thread = new Thread(q =>
{
while (true)
{
if (innerThread == null)
{
Thread.Sleep(25);
continue;
}
foreach (var highPrecisionTimer in Managers[innerThread])
{
if (highPrecisionTimer.CancelSource.IsCancellationRequested) continue;
highPrecisionTimer.TimeToRun -= 25;
if (highPrecisionTimer.TimeToRun > 0) continue;
highPrecisionTimer.Action(null);
highPrecisionTimer.TimeToRun = highPrecisionTimer.Interval;
}
Thread.Sleep(25);
}
});
innerThread = thread;
Managers.TryAdd(thread, new List<HighPrecisionTimer>());
}
}
public static void Subscribe(HighPrecisionTimer timer)
{
Thread thread = null;
var size = 0;
foreach (var manager in Managers)
{
if (thread != null && manager.Value.Count >= size) continue;
thread = manager.Key;
size = manager.Value.Count;
}
Managers[thread].Add(timer);
timer.SetThread(thread);
}
public static void Unsubscribe(HighPrecisionTimer timer)
{
Managers[timer.Thread].Remove(timer);
}
}
public class HighPrecisionTimer : IDisposable
{
public Action<object> Action { get; set; }
public CancellationTokenSource CancelSource { get; set; }
public int Interval { get; set; }
public int TimeToRun { get; set; }
public Thread Thread { get; set; }
public HighPrecisionTimer(int interval, Action<object> action)
{
Action = action;
Interval = interval;
TimeToRun = interval;
CancelSource = new CancellationTokenSource();
HighPrecisionTimerManager.Subscribe(this);
}
public void SetThread(Thread thread)
{
Thread = thread;
}
public void Dispose()
{
CancelSource.Cancel();
HighPrecisionTimerManager.Unsubscribe(this);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment