/// <summary> /// Ok time to call whatever it is we are trying to do /// </summary> private static void ExecuteWithRetryInternal(Action redisAction, IRedisRetryPolicy retryPolicy) { IRedisRetryPolicy callPolicy = null == retryPolicy ? _DefaultRetryPolicy : retryPolicy; int retryCount = callPolicy.MaxRetry; TimeSpan?delay = null; while (true) { try { redisAction(); return; } catch (Exception callError) { if (retryCount > 0 && callPolicy.ShouldRetry(callError)) { retryCount--; delay = callPolicy.CalculateDelay(retryCount); } else { throw; } } if (delay.HasValue) { //borrowed from Entity Framework execution strategy using (var waitEvent = new ManualResetEventSlim(false)) { waitEvent.WaitHandle.WaitOne(delay.Value); } } } }
/// <summary> /// In order for us to return the task, we need to create a new task /// that wraps the async action task so that it can be retried withen /// an external await /// </summary> private static Task <T> ExecuteWithRetryInternalAsync <T>(Func <Task <T> > asyncFunction, IRedisRetryPolicy retryPolicy) { IRedisRetryPolicy callPolicy = null == retryPolicy ? _DefaultRetryPolicy : retryPolicy; int retryCount = callPolicy.MaxRetry; Task <T> returnValue = Task.Run <T>(async() => { TimeSpan?delay = null; while (true) { try { T taskResult = await asyncFunction(); return(taskResult); } catch (Exception callError) { if (retryCount > 0 && callPolicy.ShouldRetry(callError)) { retryCount--; delay = callPolicy.CalculateDelay(retryCount); } else { throw; } } if (delay.HasValue) { await Task.Delay(delay.Value); } } }); return(returnValue); }