Last active
October 11, 2018 09:23
-
-
Save pglazkov/0a31862efbe7cd2d5461 to your computer and use it in GitHub Desktop.
Asynchronous Retry Helper
This file contains hidden or 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
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); | |
} | |
} |
This file contains hidden or 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
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