Exemplo n.º 1
0
        /// <summary>
        /// Attempt to execute the supplied function.
        /// </summary>
        /// <param name="numberOfAttempts">
        /// The number of attempts to try
        /// </param>
        /// <param name="interval">
        /// The amount of time to wait inbetween attempts
        /// </param>
        /// <param name="functionToAttempt">
        /// The function to try and execute
        /// </param>
        /// <param name="handleExceptions">
        /// Whether or not to handle exceptions that get thrown as part of
        /// executing the supplied function.
        /// </param>
        /// <returns>
        /// An OperationResult that denotes whether or not the function succeeded.
        /// If the function succeeded then OperationResult.Succeeded is returned.
        /// If the function failed then a failure OperationResult is returned with
        /// details of the failuer and any thrown exceptions (if handleExceptions was true)
        /// </returns>
        /// <exception cref="System.ArgumentException">
        /// Thrown if
        ///		numberOfAttempts is less than 1
        ///		interval is less than 1 millisecond
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown if
        ///		functionToAttempt is null
        /// </exception>
        public static OperationResult Attempt(
            Func <bool> functionToAttempt,
            int numberOfAttempts,
            TimeSpan interval,
            RetryExceptionBehaviour exceptionBehaviour)
        {
            #region Input validation

            Insist.IsAtLeast(numberOfAttempts, 1, "numberOfAttempts");
            Insist.IsAtLeast(interval, TimeSpan.FromMilliseconds(1), "interval");
            Insist.IsNotNull(functionToAttempt, "functionToAttempt");
            Insist.IsDefined <RetryExceptionBehaviour>(exceptionBehaviour, "exceptionBehaviour");

            #endregion

            int currentAttempts = 0;

            List <Exception> thrownExceptions = new List <Exception>();
            int numberOfThrownExceptions      = 0;

            bool usingInfiniteAttempts = numberOfAttempts == INFINITE_ATTEMPTS;

            while (currentAttempts < numberOfAttempts)
            {
                bool success = false;

                try
                {
                    success = functionToAttempt();
                }
                catch (Exception e)
                {
                    if (exceptionBehaviour == RetryExceptionBehaviour.DoNotHandle)
                    {
                        throw;
                    }
                    else if (exceptionBehaviour == RetryExceptionBehaviour.HandleAndCollate)
                    {
                        //Record the exception so that we can return information
                        //about it later on.
                        thrownExceptions.Add(e);
                        numberOfThrownExceptions++;
                    }
                    else if (exceptionBehaviour == RetryExceptionBehaviour.HandleOnly)
                    {
                        numberOfThrownExceptions++;
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("Unknown RetryExceptionBehaviour '{0}'", exceptionBehaviour));
                    }
                }

                if (success)
                {
                    return(OperationResult.Succeeded);
                }

                if (!usingInfiniteAttempts)
                //If we're using an infinite number of attempts then
                //we don't want to make any progress regards number of
                //attempts.  Just keep looping until the attempt succeeds.
                {
                    currentAttempts++;
                }

                Thread.Sleep(interval);
            }

            //If we get to this point then all attempts have failed.
            List <string> errorMessages = new List <string>();
            errorMessages.Add(string.Format("The function was not successfull after {0} attempts", numberOfAttempts));

            if (numberOfThrownExceptions > 0)
            {
                if (exceptionBehaviour == RetryExceptionBehaviour.HandleAndCollate)
                {
                    errorMessages.AddRange(thrownExceptions.Select(ex => ex.AllMessages()));
                }
                else if (exceptionBehaviour == RetryExceptionBehaviour.HandleOnly)
                {
                    errorMessages.Add(string.Format(string.Format("A total of '{0}' exceptions were thrown during the attempt", numberOfThrownExceptions)));
                }
            }

            return(new OperationResult(errorMessages));
        }
Exemplo n.º 2
0
 /// <summary>
 /// Ensures that the specified value is defined in the specified Enum
 /// </summary>
 /// <param name="value">
 /// The value to check for existance in the enum
 /// </param>
 /// <param name="argumentName">
 /// The argument name.
 /// </param>
 /// <typeparam name="T">
 /// The Enum to check the value against.
 /// </typeparam>
 public static void IsDefined <T>(T value, string argumentName) where T : struct
 {
     Insist.IsDefined <T>(value, argumentName, null);
 }