Created
February 11, 2015 13:53
-
-
Save jenyayel/3efe8616895031b4142c to your computer and use it in GitHub Desktop.
Retry mechanism
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Threading; | |
namespace RetryPolicy | |
{ | |
public class Retry | |
{ | |
/// <summary> | |
/// Implements simple retry mechanism | |
/// </summary> | |
/// <typeparam name="T">The type returned by the action</typeparam> | |
/// <param name="retryCount">How many times to retry the specified action until success is determinated</param> | |
/// <param name="shouldRetry">Predicate to determine whether we should perform the action again </param> | |
/// <param name="action">The actual action to perform</param> | |
/// <param name="retryInterval">The interval between retries</param> | |
/// <example> | |
/// Retry.Do( | |
/// 42 | |
/// (result, exception, round) => { return exception != null || result != 42; }, | |
/// () => { return new Random(DateTime.Now.Millisecond).Next(50); }); | |
/// </example> | |
/// <returns>The result of retry</returns> | |
public static RetryResult<T> Do<T>(int retryCount, Func<T, Exception, int, bool> shouldRetry, Func<T> action, TimeSpan? retryInterval = null) | |
{ | |
var _exceptions = new List<Exception>(); | |
var _result = new RetryResult<T>(); | |
for (int round = 1; round <= retryCount; round++) | |
{ | |
try | |
{ | |
var _actionResult = action(); | |
if (!shouldRetry(_actionResult, null, round)) | |
{ | |
_result.IsSuccess = true; | |
_result.Result = _actionResult; | |
_result.SuccessAfter = round; | |
break; | |
} | |
} | |
catch (Exception ex) | |
{ | |
_exceptions.Add(ex); | |
if (!shouldRetry(default(T), ex, round)) | |
break; | |
} | |
if (retryInterval.HasValue) | |
Thread.Sleep(retryInterval.Value); | |
} | |
if (_exceptions.Count > 0) | |
_result.Exception = new AggregateException(_exceptions); | |
return _result; | |
} | |
} | |
public class RetryResult<T> | |
{ | |
public bool IsSuccess { get; internal set; } | |
public T Result { get; internal set; } | |
public int SuccessAfter { get; internal set; } | |
public AggregateException Exception { get; internal set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment