Skip to content

Instantly share code, notes, and snippets.

@alexander-williamson
Last active May 28, 2017 19:04
Show Gist options
  • Save alexander-williamson/b3b75c0eec39176646d3678df083cfde to your computer and use it in GitHub Desktop.
Save alexander-williamson/b3b75c0eec39176646d3678df083cfde to your computer and use it in GitHub Desktop.
/// <summary>
/// Loop until a condition is met and your function returns true
/// </summary>
/// <param name="action">The delegate to run. Return true to exit the loop.</param>
/// <param name="delay">Return a timespan for the delay between loops</param>
/// <param name="whentoStop">Return true when the loop should stop when catching exceptions or looping</param>
public static void DoUntil(Func<bool> action, Func<int, TimeSpan, TimeSpan> delay, Func<int, TimeSpan, bool> whentoStop)
{
var startedUtc = DateTime.UtcNow;
var amountOfRetriesAllowed = 0;
while (true)
{
try
{
if (action()) return;
}
catch
{
if (whentoStop(amountOfRetriesAllowed, DateTime.UtcNow.Subtract(startedUtc))) throw;
}
finally
{
amountOfRetriesAllowed++;
}
var calculatedDelay = delay(amountOfRetriesAllowed, DateTime.UtcNow.Subtract(startedUtc));
if (calculatedDelay.TotalMilliseconds < 0)
{
calculatedDelay = TimeSpan.Zero;
}
Thread.Sleep(calculatedDelay);
}
}
@alexander-williamson
Copy link
Author

Example:

DoUntil(() => worker.DoesSomethingAndReturnsTrue(), (i, t) => TimeSpan.Zero, (i, t) => i < 100);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment