예제 #1
0
 public static TResult Execute <TResult>(
     TryParameterlessAction <TResult> action,
     long retryIntervalMs,
     long retryCount                   = -1,
     bool suppressExceptions           = true,
     int consecutiveFailuresUntilAbort = 10
     )
 {
     return(Execute(
                action, new TimeSpan(retryIntervalMs * TimeSpan.TicksPerMillisecond), retryCount, suppressExceptions,
                consecutiveFailuresUntilAbort
                ));
 }
예제 #2
0
        public static TResult Execute <TResult>(
            TryParameterlessAction <TResult> action,
            TimeSpan retryInterval,
            long retryCount                   = -1,
            bool suppressExceptions           = true,
            int consecutiveFailuresUntilAbort = 10
            )
        {
            if (retryInterval.TotalMilliseconds < 1000)
            {
                throw new InvalidOperationException("You should not use this class for small intervals.");
            }

            if (retryInterval.TotalMilliseconds < 2000)
            {
                Log.Warn("You should probably not be using Retry if you need such short intervals.");
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var result = default(TResult);

            var caughtExceptions      = new List <Exception>();
            var consecutiveExceptions = 0;
            var retriesRemaining      = retryCount;

            while (retriesRemaining == -1 || 0 < retriesRemaining)
            {
                try
                {
                    Thread.Sleep(retryInterval);

                    if (action(out result))
                    {
                        return(result);
                    }

                    consecutiveExceptions = 0;
                    caughtExceptions.Clear();
                }
                catch (Exception exception)
                {
                    caughtExceptions.Add(exception);
                    if (++consecutiveExceptions >= consecutiveFailuresUntilAbort)
                    {
                        DumpExceptions(caughtExceptions);

                        throw new OperationCanceledException("Failed too many times consecutively, aborting.");
                    }
                }

                if (--retriesRemaining == 0)
                {
                    break;
                }
            }

            if (caughtExceptions.Count <= 0 || suppressExceptions)
            {
                return(result);
            }

            DumpExceptions(caughtExceptions);

            throw caughtExceptions.FindLast(e => true) ?? new InvalidOperationException("Bad Retry state!");
        }