Created
June 22, 2017 16:23
-
-
Save Brian1KB/d552b6895e71ca90cd15c4d4f72653cd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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