public TResult ExecuteAction <TResult>( RandomSourceFunc <TSource, TResult> func, ShouldRetryPredicate shouldRetry, OnError onError = null) { if (typeof(Task).IsAssignableFrom(typeof(TResult))) { throw new ArgumentException( "Async action should be executed with ExecuteAsync.", nameof(func)); } for (var attemptCount = 1; ; attemptCount++) { var item = _chooseRandomly(); try { var result = func(item, attemptCount); _updateWeight(item, true); return(result); } catch (Exception e) { onError?.Invoke(e, attemptCount); _updateWeight(item, false); if (!shouldRetry(attemptCount, e)) { throw; } } } }
// TODO: Test public static TResult ExecuteAction <TSource, TResult>( this IResourceManager <TSource> mgr, RandomSourceFunc <TSource, TResult> func, ShouldRetryPredicate shouldRetry, OnError onError = null) { var retryAction = new RetryAction <TSource>(mgr.SelectRandomly, mgr.UpdateWeight); return(retryAction.ExecuteAction(func, shouldRetry, onError)); }