Skip to content

Instantly share code, notes, and snippets.

@pglazkov
Last active October 11, 2018 09:23
Show Gist options
  • Save pglazkov/0a31862efbe7cd2d5461 to your computer and use it in GitHub Desktop.
Save pglazkov/0a31862efbe7cd2d5461 to your computer and use it in GitHub Desktop.
Asynchronous Retry Helper
public static class AsyncRetry
{
public static async Task DoAsync(Func<Task> action,
AsyncRetryPolicy policy = null,
CancellationToken? cancellationToken = null)
{
await DoAsync(async () =>
{
await action();
return true;
},
policy, cancellationToken);
}
public static async Task<T> DoAsync<T>(Func<Task<T>> action,
AsyncRetryPolicy policy = null,
CancellationToken? cancellationToken = null)
{
cancellationToken = cancellationToken ?? CancellationToken.None;
policy = policy ?? new AsyncRetryPolicy();
var uniqueExceptions = new Dictionary<string, Exception>();
for (var retry = 0; retry < policy.RetryCount; retry++)
{
try
{
cancellationToken.Value.ThrowIfCancellationRequested();
return await action();
}
catch (Exception ex) when (!(ex is OperationCanceledException) && policy.ExceptionFilter(ex))
{
if (!uniqueExceptions.ContainsKey(ex.Message))
{
uniqueExceptions.Add(ex.Message, ex);
}
if (retry < policy.RetryCount - 1)
{
try
{
policy.OnExceptionAction(ex);
}
catch (Exception) { }
await Task.Delay(policy.RetryInterval, cancellationToken.Value);
}
}
}
throw new AggregateException(uniqueExceptions.Values);
}
}
public class AsyncRetryPolicy
{
public AsyncRetryPolicy(TimeSpan? retryInterval = null,
int retryCount = 3,
Func<Exception, bool> exceptionFilter = null,
Action<Exception> onExceptionAction = null)
{
RetryInterval = retryInterval ?? TimeSpan.FromSeconds(3);
RetryCount = retryCount;
ExceptionFilter = exceptionFilter ?? (ex => true);
OnExceptionAction = onExceptionAction ?? (ex => { });
}
public TimeSpan RetryInterval { get; private set; }
public int RetryCount { get; private set; }
public Func<Exception, bool> ExceptionFilter { get; private set; }
public Action<Exception> OnExceptionAction { get; private set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment