Skip to content

Instantly share code, notes, and snippets.

@Buildstarted
Created January 20, 2012 22:16
Show Gist options
  • Save Buildstarted/1649910 to your computer and use it in GitHub Desktop.
Save Buildstarted/1649910 to your computer and use it in GitHub Desktop.
Perform.This() method for initiating delayed and repeating actions
public class Perform
{
private readonly Action _action;
private int _delay;
private int _interval = Timeout.Infinite;
private int _iterations = int.MinValue;
private int _iterationsPerformed = 0;
private Timer _timer;
private int _until;
public static Perform This(Action action)
{
return new Perform(action);
}
internal Perform(Action action)
{
if (action == null) throw new ArgumentNullException("action");
_action = action;
}
public Perform Every(TimeSpan timeSpan)
{
CheckArgumentNotNegative(timeSpan, "timeSpan");
return Every((int)timeSpan.TotalMilliseconds);
}
public Perform Every(int milliseconds)
{
CheckArgumentNotNegative(milliseconds, "milliseconds");
_interval = milliseconds;
return this;
}
public Perform In(TimeSpan timeSpan)
{
CheckArgumentNotNegative(timeSpan, "timeSpan");
return In((int)timeSpan.TotalMilliseconds);
}
public Perform In(int milliseconds)
{
CheckArgumentNotNegative(milliseconds, "milliseconds");
_delay = milliseconds;
return this;
}
public Perform For(int iterations)
{
CheckArgumentNotNegative(iterations, "iterations");
_iterations = iterations;
return this;
}
public Perform For(TimeSpan timeSpan)
{
CheckArgumentNotNegative(timeSpan, "timeSpan");
_until = (int)timeSpan.TotalMilliseconds;
return this;
}
public void Start()
{
DateTime start = DateTime.UtcNow;
_timer = new Timer(_ => {
_action();
_iterationsPerformed += 1;
CheckFinished(start);
}, null, _delay, _interval);
}
private void CheckFinished(DateTime start)
{
if ((_iterations != int.MinValue && _iterationsPerformed >= _iterations) ||
(_until != int.MinValue && start.AddMilliseconds(_until) < DateTime.UtcNow)) {
_timer.Dispose();
}
}
//This is for future implementations
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
[DebuggerStepThrough]
private static void CheckArgumentNotNegative(int checkArgument, string argument)
{
if (checkArgument < 0) {
throw new ArgumentOutOfRangeException(argument, argument + " must be non-negative");
}
}
[DebuggerStepThrough]
private static void CheckArgumentNotNegative(TimeSpan timeSpan, string argument)
{
CheckArgumentNotNegative((int) timeSpan.TotalMilliseconds, argument);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment