Skip to content

Instantly share code, notes, and snippets.

@ctigeek
Created December 5, 2016 01:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctigeek/e2376848056f43df45069d587efa0645 to your computer and use it in GitHub Desktop.
Save ctigeek/e2376848056f43df45069d587efa0645 to your computer and use it in GitHub Desktop.
Run an Action periodically....
public class Periodic : IDisposable
{
private static readonly object lockObject = new object();
private readonly List<PeriodicEvent> history = new List<PeriodicEvent>();
private readonly Action action;
private readonly Timer timer;
private long id = 0;
public PeriodicEvent LatestEvent { get; private set; }
public Periodic(TimeSpan timeSpan, Action action)
{
this.action = action;
timer = new Timer(Callback, null, timeSpan, timeSpan);
}
public bool SaveHistory { get; set; } = false;
public IReadOnlyList<PeriodicEvent> History => new ReadOnlyCollection<PeriodicEvent>(history);
public void Stop()
{
timer?.Dispose();
}
public void Dispose()
{
Stop();
}
private void Callback(object o)
{
var startTime = DateTime.UtcNow;
var outcome = PeriodicOutcome.Complete;
Exception exception = null;
var eventId = Interlocked.Increment(ref id);
if (Monitor.TryEnter(lockObject))
{
try
{
action();
}
catch (Exception ex)
{
exception = ex;
outcome = PeriodicOutcome.Error;
}
finally
{
Monitor.Exit(lockObject);
}
}
else
{
outcome = PeriodicOutcome.Missed;
}
var periodicEvent = new PeriodicEvent(eventId, startTime, DateTime.UtcNow, this, outcome, exception);
LatestEvent = periodicEvent;
if (SaveHistory) history.Add(periodicEvent);
}
}
public enum PeriodicOutcome
{
Complete,
Error,
Missed
}
public class PeriodicEvent
{
public readonly long Id;
public readonly PeriodicOutcome Outcome;
public readonly DateTime UtcStart;
public readonly DateTime UtcFinish;
public readonly Periodic Periodic;
public readonly Exception Error;
public PeriodicEvent(long id, DateTime start, DateTime finish, Periodic periodic, PeriodicOutcome periodicOutcome = PeriodicOutcome.Complete, Exception error = null)
{
Id = id;
Periodic = periodic;
Outcome = periodicOutcome;
UtcStart = start;
UtcFinish = finish;
Error = error;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment