Skip to content

Instantly share code, notes, and snippets.

@abdallaadelessa
Last active February 8, 2018 10:15
Show Gist options
  • Save abdallaadelessa/2964b2c0d35590e48ff71faa4d92a89f to your computer and use it in GitHub Desktop.
Save abdallaadelessa/2964b2c0d35590e48ff71faa4d92a89f to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace BSSConsumer.Core
{
public static class FuncUtils
{
public static readonly IRetryPolicy DefaultRetryPolicy = new FibonacciRetryPolicy();
public static Task<T> Retry<T>(this Func<Task<T>> func, int maxNumOfRetries, CancellationToken token)
{
return RetryFunc(func, 0, maxNumOfRetries, token, DefaultRetryPolicy);
}
public static Task<T> Retry<T>(this Func<Task<T>> func, int maxNumOfRetries, CancellationToken token, IRetryPolicy retryPolicy)
{
return RetryFunc(func, 0, maxNumOfRetries, token, retryPolicy);
}
public interface IRetryPolicy
{
int GetWaitTime(int currentRetryNum);
}
private class FibonacciRetryPolicy : IRetryPolicy
{
public int GetWaitTime(int n)
{
if (n <= 1) return n;
else return GetWaitTime(n - 1) + GetWaitTime(n - 2);
}
}
#region Main
private async static Task<T> RetryFunc<T>(Func<Task<T>> func, int currentRetryNum, int maxNumOfRetries, CancellationToken token, IRetryPolicy retryPolicy)
{
try
{
int waitTime = (retryPolicy.GetWaitTime(currentRetryNum) * 1000);
await Task.Delay(waitTime, token);
return await func.Invoke();
}
catch (Exception ex)
{
if (currentRetryNum < maxNumOfRetries && !token.IsCancellationRequested)
{
return await RetryFunc(func, ++currentRetryNum, maxNumOfRetries, token, retryPolicy);
}
else
{
throw ex;
}
}
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment