Skip to content

Instantly share code, notes, and snippets.

@lbargaoanu
Created March 4, 2017 17:35
Show Gist options
  • Save lbargaoanu/914584756f17abf945a3075ac2c1c6fd to your computer and use it in GitHub Desktop.
Save lbargaoanu/914584756f17abf945a3075ac2c1c6fd to your computer and use it in GitHub Desktop.
namespace Scheduler
{
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections.Generic;
public static class UIJobScheduler
{
static readonly List<Job> jobs = new List<Job>();
static readonly Timer timer = new Timer();
class Job
{
readonly Action<object> action;
readonly object state;
readonly int interval;
DateTime nextRunDate;
public Job(int millisecondsInterval, Action<object> action, object state)
{
this.action = action;
this.state = state;
this.nextRunDate = TruncatedUtcNow();
interval = millisecondsInterval;
}
public void CheckExecute(ref DateTime utcNow)
{
Debug.WriteLine("[CheckExecute] Now: " + utcNow.ToString("mm:ss.fff") + " nextRunDate: " + nextRunDate.ToString("mm:ss.fff") + " interval: " + interval);
if(nextRunDate > utcNow)
{
return;
}
nextRunDate = utcNow.AddMilliseconds(interval);
try
{
action(state);
}
catch(Exception ex)
{
Trace.WriteLine(ex);
}
}
}
static UIJobScheduler()
{
timer.Tick += new EventHandler(TimerFunction);
timer.Start();
}
static void TimerFunction(object sender, EventArgs e)
{
DateTime utcNow = TruncatedUtcNow();
foreach(Job job in jobs)
{
job.CheckExecute(ref utcNow);
}
}
public static void Register(int millisecondsInterval, Action<object> action)
{
Register(millisecondsInterval, action, null);
}
public static void Register(int millisecondsInterval, Action<object> action, object state)
{
if(millisecondsInterval <= 0)
{
throw new ArgumentOutOfRangeException("millisecondsInterval");
}
if(action == null)
{
throw new ArgumentNullException("action");
}
Job job = new Job(millisecondsInterval, action, state);
jobs.Add(job);
timer.Interval = Gcd(millisecondsInterval, timer.Interval);
}
static DateTime TruncatedUtcNow()
{
DateTime utcNow = DateTime.UtcNow;
return new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, utcNow.Hour, utcNow.Minute, utcNow.Second, utcNow.Millisecond);
}
static int Gcd(int a, int b)
{
while(b != 0)
{
int oldA = a;
a = b;
b = oldA % b;
}
return a;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment