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();
}