public abstract TimeSpan? CalculateRetryDelay()

in src/Microsoft.Azure.NotificationHubs/NotificationHubRetryPolicy.cs [39:112]


        public abstract TimeSpan? CalculateRetryDelay(
            Exception lastException,
            int attemptCount);

        /// <summary>
        ///   Determines whether the specified <see cref="object" /> is equal to this instance.
        /// </summary>
        ///
        /// <param name="obj">The <see cref="object" /> to compare with this instance.</param>
        ///
        /// <returns><c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
        ///
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Equals(object obj) => base.Equals(obj);

        /// <summary>
        ///   Returns a hash code for this instance.
        /// </summary>
        ///
        /// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
        ///
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override int GetHashCode() => base.GetHashCode();

        /// <summary>
        ///   Converts the instance to string representation.
        /// </summary>
        ///
        /// <returns>A <see cref="string" /> that represents this instance.</returns>
        ///
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override string ToString() => base.ToString();

        /// <summary>
        ///
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async Task<T> RunOperation<T>(
            Func<CancellationToken, Task<T>> operation,
            CancellationToken cancellationToken)
        {
            var failedAttemptCount = 0;


            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    return await operation(cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    // Determine if there should be a retry for the next attempt; if so enforce the delay but do not quit the loop.
                    // Otherwise, throw the translated exception.

                    ++failedAttemptCount;
                    TimeSpan? retryDelay = CalculateRetryDelay(ex, failedAttemptCount);
                    if (retryDelay.HasValue && !cancellationToken.IsCancellationRequested)
                    {
                        await Task.Delay(retryDelay.Value, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        ExceptionDispatchInfo.Capture(ex)
                            .Throw();
                    }
                }
            }
            // If no value has been returned nor exception thrown by this point,
            // then cancellation has been requested.
            throw new TaskCanceledException();
        }