0Pricing
C# Academy · Leçon

Principes de résilience : nouvelles tentatives et temporisation progressive

Implémentez de simples nouvelles tentatives avec temporisation exponentielle et variation aléatoire ; distinguez les erreurs temporaires des erreurs fatales, plafonnez les délais et arrêtez-vous en cas d’annulation.

Principes de résilience : nouvelles tentatives et temporisation progressive est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 3. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 3 leçons au total.

Pourquoi utiliser les nouvelles tentatives et la temporisation progressive

Objectif : rendre les appels résilients.

  • Réessayer en cas d’échecs transitoires
  • Utiliser une temporisation exponentielle avec une gigue
  • Définir un nombre maximal de tentatives et un délai maximal
  • S’arrêter en cas d’erreurs fatales ou d’annulation

Classer les échecs

Transitoires : délais d’expiration, réponses 429/5xx, perturbations réseau temporaires.

Fatales : requête incorrecte, accès non autorisé, erreurs de validation — ne pas réessayer.

Règle : ne réessayez que ce qui peut réussir ultérieurement.

Assistant de temporisation progressive

Un petit assistant augmente le délai à chaque tentative et ajoute une petite gigue ; il plafonne également le délai maximal.

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

public static class Backoff
{
  // Compute delay = min(base * 2^attempt, cap) + jitter
  public static int ComputeDelayMs(int attempt, int baseMs, int capMs, int jitterMs, Random rng)
  {
    long exp = (long)baseMs << attempt; // base * 2^attempt
    if (exp > capMs) exp = capMs;
    int jitter = rng.Next(0, jitterMs + 1); // [0..jitterMs]
    return (int)exp + jitter;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    Random rng = new Random(123);
    for (int i = 0; i < 5; i++)
    {
      int d = Backoff.ComputeDelayMs(i, 100, 2000, 50, rng);
      Console.WriteLine("Attempt " + i + " -> " + d + " ms");
    }
  }
}

Enveloppe de nouvelle tentative

Entourez l’appel : réessayez uniquement en cas d’exceptions transitoires et arrêtez-vous dans les autres cas. Chaque nouvelle tentative attend plus longtemps, avec une gigue.

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

public class Program
{
  static readonly Random Rng = new Random();

  // Simulate an operation that sometimes fails transiently.
  static async Task<string> FlakyAsync()
  {
    await Task.Delay(60);
    // 50% chance of transient failure
    if (DateTime.UtcNow.Ticks % 2 == 0) throw new TimeoutException("Transient");
    return "OK";
  }

  static async Task<T> RetryAsync<T>(Func<Task<T>> action, int maxAttempts)
  {
    int baseMs = 100, capMs = 2000, jitterMs = 50;
    for (int attempt = 0; attempt < maxAttempts; attempt++)
    {
      try
      {
        return await action();
      }
      catch (TimeoutException)
      {
        if (attempt == maxAttempts - 1) throw; // out of retries
        int delay = Backoff.ComputeDelayMs(attempt, baseMs, capMs, jitterMs, Rng);
        await Task.Delay(delay);
      }
      catch (Exception)
      {
        // Non-transient (unknown) -> do not retry
        throw;
      }
    }
    throw new InvalidOperationException("Unreachable");
  }

  public static void Main(string[] args)
  {
    try
    {
      string s = RetryAsync(FlakyAsync, 5).GetAwaiter().GetResult();
      Console.WriteLine("Result: " + s);
    }
    catch (Exception ex)
    {
      Console.WriteLine("Failed: " + ex.GetType().Name);
    }
  }
}

Nouvelles tentatives limitées par un budget

Ajoutez un budget global au moyen de l’annulation : transmettez les jetons à la fois à l’opération et aux délais de temporisation progressive.

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

public static class RetryUtil
{
  static readonly Random Rng = new Random();

  public static async Task<T> RetryAsync<T>(Func<CancellationToken, Task<T>> action, int maxAttempts, CancellationToken ct)
  {
    int baseMs = 100, capMs = 1500, jitterMs = 50;
    for (int attempt = 0; attempt < maxAttempts; attempt++)
    {
      ct.ThrowIfCancellationRequested();
      try
      {
        return await action(ct);
      }
      catch (TimeoutException)
      {
        if (attempt == maxAttempts - 1) throw;
        int delay = Backoff.ComputeDelayMs(attempt, baseMs, capMs, jitterMs, Rng);
        await Task.Delay(delay, ct); // pass token so we can abort waiting
      }
    }
    throw new InvalidOperationException("Unreachable");
  }
}

public class Program
{
  static async Task<string> SometimesSlowAsync(CancellationToken ct)
  {
    await Task.Delay(200, ct);
    if (DateTime.UtcNow.Millisecond % 3 != 0) throw new TimeoutException("Transient");
    return "OK";
  }

  public static void Main(string[] args)
  {
    var cts = new CancellationTokenSource();
    cts.CancelAfter(800); // overall budget

    try
    {
      string s = RetryUtil.RetryAsync(SometimesSlowAsync, 5, cts.Token).GetAwaiter().GetResult();
      Console.WriteLine("Done: " + s);
    }
    catch (OperationCanceledException) { Console.WriteLine("Canceled"); }
    catch (Exception ex) { Console.WriteLine("Failed: " + ex.Message); }
  }
}

Recommandations

Conseils :

  • Ne réessayez que les appels idempotents.
  • Utilisez des plafonds pour le nombre de tentatives et le délai.
  • Ajoutez une petite gigue pour éviter les effets de troupeau.
  • Journalisez l’échec final avec sa raison et le nombre de tentatives.

Définition de la temporisation progressive

Vérification rapide : quelle description correspond le mieux à une temporisation exponentielle avec gigue ?

Récapitulatif

Récapitulatif : réessayez uniquement en cas d’erreurs transitoires, augmentez les délais de manière exponentielle avec un plafond, ajoutez une gigue et arrêtez-vous en cas d’annulation ou d’erreurs fatales.

Questions Fréquemment Posées

La leçon « Principes de résilience : nouvelles tentatives et temporisation progressive » est-elle gratuite ?

Oui — le texte complet de « Principes de résilience : nouvelles tentatives et temporisation progressive » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 3 leçons au total.

Qu'est-ce que j'apprendrai dans « Principes de résilience : nouvelles tentatives et temporisation progressive » ?

Implémentez de simples nouvelles tentatives avec temporisation exponentielle et variation aléatoire ; distinguez les erreurs temporaires des erreurs fatales, plafonnez les délais et arrêtez-vous en c… Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C# Academy ?

Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 3.

Combien de temps prend la leçon « Principes de résilience : nouvelles tentatives et temporisation progressive » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?

Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Modèles CancellationToken et annulation coopérative
  2. Délais d’expiration, IProgress et ressources asynchrones (émulation)
  3. Principes de résilience : nouvelles tentatives et temporisation progressive
← Retour à C# Academy