Occasionally I have a need to retry an operation several times before giving up. My code is like:
int retries = 3;
while(true) {
try {
DoSomething();
I had the need to pass some parameter to my method to retry, and have a result value; so i need an expression.. I build up this class that does the work (it is inspired to the the LBushkin's one) you can use it like this:
static void Main(string[] args)
{
// one shot
var res = Retry.Do(() => retryThis("try"), 4, TimeSpan.FromSeconds(2), fix);
// delayed execute
var retry = new Retry(() => retryThis("try"), 4, TimeSpan.FromSeconds(2), fix);
var res2 = retry.Execute();
}
static void fix()
{
Console.WriteLine("oh, no! Fix and retry!!!");
}
static string retryThis(string tryThis)
{
Console.WriteLine("Let's try!!!");
throw new Exception(tryThis);
}
public class Retry
{
Expression> _Method;
int _NumRetries;
TimeSpan _RetryTimeout;
Action _OnFailureAction;
public Retry(Expression> method, int numRetries, TimeSpan retryTimeout, Action onFailureAction)
{
_Method = method;
_NumRetries = numRetries;
_OnFailureAction = onFailureAction;
_RetryTimeout = retryTimeout;
}
public TResult Execute()
{
TResult result = default(TResult);
while (_NumRetries > 0)
{
try
{
result = _Method.Compile()();
break;
}
catch
{
_OnFailureAction();
_NumRetries--;
if (_NumRetries <= 0) throw; // improved to avoid silent failure
Thread.Sleep(_RetryTimeout);
}
}
return result;
}
public static TResult Do(Expression> method, int numRetries, TimeSpan retryTimeout, Action onFailureAction)
{
var retry = new Retry(method, numRetries, retryTimeout, onFailureAction);
return retry.Execute();
}
}
ps. the LBushkin's solution does one more retry =D