Skip to content

Instantly share code, notes, and snippets.

@swagfin
Last active June 27, 2025 19:59
Show Gist options
  • Select an option

  • Save swagfin/02f0b7ce472a0c6e1ef185a137495a96 to your computer and use it in GitHub Desktop.

Select an option

Save swagfin/02f0b7ce472a0c6e1ef185a137495a96 to your computer and use it in GitHub Desktop.

πŸ” WithRetry Helper for C#

A minimal retry utility for async methods with and without return values.

πŸ“¦ Code

using System;
using System.Threading;
using System.Threading.Tasks;

public static class WithRetry
{
    /// <summary>
    /// Retries an asynchronous function that returns a result (Task&lt;T&gt;).
    /// </summary>
    public static async Task<T> TaskAsync<T>(Func<Task<T>> operation, int maxRetries = 2, TimeSpan? delay = null, CancellationToken cancellationToken = default)
    {
        if (operation == null) throw new ArgumentNullException(nameof(operation));
        if (maxRetries < 0) throw new ArgumentOutOfRangeException(nameof(maxRetries));

        delay = delay ?? TimeSpan.FromSeconds(1);

        for (int attempt = 1; ; attempt++)
        {
            try
            {
                cancellationToken.ThrowIfCancellationRequested();
                return await operation().ConfigureAwait(false);
            }
            catch (Exception ex) when (attempt < maxRetries)
            {
                Console.WriteLine($"[Attempt {attempt}] Failed, Error: {ex.Message}");
                await Task.Delay(delay.Value, cancellationToken).ConfigureAwait(false);
            }
        }
    }

    /// <summary>
    /// Retries an asynchronous function that does not return a result (Task).
    /// </summary>
    public static async Task TaskAsync(Func<Task> operation, int maxRetries = 2, TimeSpan? delay = null, CancellationToken cancellationToken = default)
    {
        if (operation == null) throw new ArgumentNullException(nameof(operation));
        if (maxRetries < 0) throw new ArgumentOutOfRangeException(nameof(maxRetries));

        delay = delay ?? TimeSpan.FromSeconds(1);

        for (int attempt = 1; ; attempt++)
        {
            try
            {
                cancellationToken.ThrowIfCancellationRequested();
                await operation().ConfigureAwait(false);
                return;
            }
            catch (Exception ex) when (attempt < maxRetries)
            {
                Console.WriteLine($"[Attempt {attempt}] Failed, Error: {ex.Message}");
                await Task.Delay(delay.Value, cancellationToken).ConfigureAwait(false);
            }
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment