AIDE .NET

Polly Retry (Comment ça marche pour les développeurs)

La gestion des erreurs transitoires, des dépassements de délai et des exceptions de manière gracieuse est cruciale pour la construction d'applications robustes et résilientes. Polly est une bibliothèque .NET populaire qui offre des capacités de résilience et de gestion des défaillances transitoires. Parmi ses nombreuses fonctionnalités, le "retry" est l'une des politiques les plus utilisées.

Dans cet article, nous allons approfondir la politique de réessai de Polly en C#, explorer son utilisation, ses options de configuration, et fournir des exemples de code pratiques. Nous utiliserons également la bibliothèque IronPDF pour la génération de PDF avec la tentative de réessai Polly pour générer un PDF des résultats de la demande de formulaire.

Qu'est-ce que Polly Retry ?

Polly Retry est une politique fournie par la bibliothèque Polly qui permet aux développeurs de réessayer automatiquement les opérations qui pourraient échouer en raison d'une erreur ou de défauts transitoires. Les erreurs transitoires sont des erreurs temporaires qui se produisent en raison de problèmes de réseau, d'indisponibilité du service ou d'autres problèmes transitoires.

Avec la politique de réessai de Polly, vous pouvez définir des règles pour les opérations de réessai, y compris le nombre maximum de réessais, le délai entre plusieurs réessais et les conditions de réessai d'une demande qui a échoué. Cela permet de construire des applications résilientes qui peuvent se remettre de défaillances temporaires sans tomber en panne ou provoquer des interruptions pour les utilisateurs finaux.

Démarrer avec Polly Retry

Avant de nous plonger dans les exemples de code, nous allons comprendre comment installer et configurer Polly dans un projet C#.

Installation de Polly

Vous pouvez installer Polly via la console NuGet Package Manager en utilisant la commande suivante :

Install-Package Polly
Install-Package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package Polly
$vbLabelText   $csharpLabel

Ou via l'interface de programmation .NET :

dotnet add package Polly
dotnet add package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package Polly
$vbLabelText   $csharpLabel

Ajout de Polly à l'aide de déclarations

Dans votre fichier C#, incluez l'espace de noms Polly :

using Polly;
using Polly;
Imports Polly
$vbLabelText   $csharpLabel

Exemple de politique de rappel de base

Commençons par un exemple simple dans lequel nous essayons à nouveau une opération qui simule la récupération de données à partir d'un service distant. Nous allons mettre en place une politique de réessai avec un maximum de 3 réessais et un délai fixe de 2 secondes entre les réessais.

using System;
using System.Net.Http;
using Polly;
namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
           var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetry(
                    3,
                    retryAttempt => TimeSpan.FromSeconds(2),
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });
            try
            {
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
using System;
using System.Net.Http;
using Polly;
namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
           var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetry(
                    3,
                    retryAttempt => TimeSpan.FromSeconds(2),
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });
            try
            {
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
Imports System
Imports System.Net.Http
Imports Polly
Namespace PollyRetryExample
	Public Class Program
		Public Shared Sub Main(ByVal args() As String)
		   Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
			   Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message)
		   End Sub)
			Try
				retryPolicy.Execute(Sub()
					FetchDataFromRemoteService()
				End Sub)
			Catch ex As Exception
				Console.WriteLine("Failed after 3 retries: {0}", ex.Message)
			End Try
		End Sub
		Public Shared Sub FetchDataFromRemoteService()
			Throw New HttpRequestException("Failed to fetch data from remote service")
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

Dans cet exemple :

  • Handle<HttpRequestException>() spécifie que nous voulons gérer HttpRequestException et réessayer l'opération si cela se produit.
  • WaitAndRetry() configure la politique de réessai avec 3 tentatives et un délai fixe de 2 secondes entre les tentatives (durée maximale spécifiée).
  • Le délégué onRetry enregistre un message lorsqu'une nouvelle tentative se produit.

    Polly Retry (Comment cela fonctionne pour les développeurs) : Figure 1

Configuration avancée de la politique de rappel

Retard exponentiel

Le backoffing exponentiel est une stratégie de relance populaire dans laquelle le délai entre les demandes et les relances augmente de manière exponentielle. Polly offre un moyen pratique d'implémenter la remontée exponentielle en utilisant WaitAndRetry().

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(Math.Pow(2, attempt)), onRetry:= Sub(exception, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
$vbLabelText   $csharpLabel

Polly Retry (Comment ça fonctionne pour les développeurs) : Figure 2

Réessayer avec le disjoncteur

La combinaison de la relance avec un disjoncteur peut encore améliorer la résilience en empêchant les relances répétées lorsqu'un service est constamment défaillant. Polly vous permet de combiner facilement les politiques de réessai et de disjoncteur.

var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromSeconds(30),
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromSeconds(30),
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
Dim circuitBreakerPolicy = Policy.Handle(Of HttpRequestException)().CircuitBreaker(exceptionsAllowedBeforeBreaking:= 3, durationOfBreak:= TimeSpan.FromSeconds(30), onBreak:= Sub(ex, breakDelay)
			Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.")
End Sub, onReset:= Sub()
			Console.WriteLine("Circuit reset.")
End Sub)
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(2), onRetry:= Sub(exception, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
Dim policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy)
$vbLabelText   $csharpLabel

Dans cet exemple :

  • CircuitBreaker() définit une politique de disjoncteur qui déclenche après 3 exceptions et reste ouverte pendant 30 secondes.
  • Policy.Wrap() combine les politiques de disjoncteur et de réessai en une seule politique.

    Polly Retry (Comment ça fonctionne pour les développeurs) : Figure 3

Introduction à IronPDF

Présentation de la bibliothèque PDF IronPDF C# est une puissante bibliothèque C# qui permet aux développeurs de créer, éditer et manipuler des documents PDF au sein de leurs applications .NET. Que vous ayez besoin de créer des factures, des rapports ou tout autre type de document PDF, IronPDF propose une API intuitive qui simplifie le processus.

Avec IronPDF, vous pouvez facilement convertir des pages web HTML, CSS et même ASP.NET en PDF, ce qui en fait un outil polyvalent pour un grand nombre d'applications. En outre, il offre des fonctionnalités avancées telles que l'ajout de texte, d'images et d'éléments interactifs aux PDF, ainsi que la sécurisation de ces derniers par le chiffrement et les signatures numériques.

IronPDF excelle dans la conversion HTML en PDF, garantissant la préservation précise des mises en page et des styles d'origine. Il est parfait pour générer des PDFs à partir de contenu web tel que des rapports, des factures et de la documentation. IronPDF prend en charge la conversion de fichiers HTML, d'URL et de chaînes HTML brutes en fichiers PDF de haute qualité.

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Polly Retry avec IronPDF

Lorsque vous travaillez avec IronPDF, il peut arriver que vous ayez besoin d'extraire des données de sources externes ou d'effectuer des opérations complexes avant de générer un PDF.

Dans de tels cas, vous pouvez rencontrer des défauts transitoires ou des problèmes temporaires qui peuvent entraîner des échecs de génération de PDF. Pour traiter ces erreurs transitoires avec élégance, vous pouvez utiliser Polly Retry en conjonction avec IronPDF.

Installation d'IronPDF et de Polly

Avant de commencer, assurez-vous d'installer le paquetage NuGet IronPDF dans votre projet.

Install-Package IronPdf

Utilisation de Polly Retry avec IronPDF

Examinons un exemple dans lequel nous utilisons Polly Retry pour gérer les erreurs transitoires lors de la génération d'un PDF à l'aide d'IronPDF. Dans l'exemple suivant, nous simulerons la récupération de données à partir d'une API externe, puis la génération d'un PDF sur la base de ces données. Nous utiliserons Polly Retry pour exécuter l'opération de récupération des données en cas d'échecs.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;
namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetryAsync(
                    3,//retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2),//calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync();
                return GeneratePdfFromData(data);
            });
            pdf.SaveAs("GeneratedDocument.pdf");
        }
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            // Simulate fetching data from an external API
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }
        static PdfDocument GeneratePdfFromData(string data)
        {
            // Generate PDF using IronPDF based on the fetched data
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;
namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetryAsync(
                    3,//retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2),//calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync();
                return GeneratePdfFromData(data);
            });
            pdf.SaveAs("GeneratedDocument.pdf");
        }
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            // Simulate fetching data from an external API
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }
        static PdfDocument GeneratePdfFromData(string data)
        {
            // Generate PDF using IronPDF based on the fetched data
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports IronPdf
Imports Polly
Namespace IronPdfWithPollyRetry
	Public Class Program
		Public Shared Async Function Main(ByVal args() As String) As Task
			Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetryAsync(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
				Console.WriteLine("Retry " & retryCount & " due to " & exception.Message)
			End Sub)
			Dim pdf = Await retryPolicy.ExecuteAsync(Async Function()
				Dim data = Await FetchDataFromExternalApiAsync()
				Return GeneratePdfFromData(data)
			End Function)
			pdf.SaveAs("GeneratedDocument.pdf")
		End Function
		Private Shared Async Function FetchDataFromExternalApiAsync() As Task(Of String)
			' Simulate fetching data from an external API
			Await Task.Delay(100) ' Simulate delay
			Throw New HttpRequestException("Failed to fetch data from external API")
		End Function
		Private Shared Function GeneratePdfFromData(ByVal data As String) As PdfDocument
			' Generate PDF using IronPDF based on the fetched data
			Dim htmlContent = "<html><body><h1>Data: " & data & "</h1></body></html>"
			Dim renderer = New ChromePdfRenderer()
			Return renderer.RenderHtmlAsPdf(htmlContent)
		End Function
	End Class
End Namespace
$vbLabelText   $csharpLabel

Ce code C# montre comment utiliser la bibliothèque Polly pour mettre en œuvre des politiques de relance avec IronPDF pour générer un document PDF. La méthode Main initialise une politique de nouvelle tentative en utilisant la méthode WaitAndRetryAsync de Polly.

Cette politique spécifie qu'elle doit gérer HttpRequestException et réessayer l'opération jusqu'à 3 fois avec un délai de 2 secondes entre la tentative initiale et les réessais. En cas d'échec de la tentative, un message est imprimé sur la console, indiquant le numéro de la tentative et le message d'exception.

À l'intérieur de la méthode Main, la logique de la politique de nouvelle tentative est exécutée de manière asynchrone en utilisant retryPolicy.ExecuteAsync(). DANS cette exécution, deux opérations asynchrones sont enchaînées : FetchDataFromExternalApiAsync() et GeneratePdfFromData(data).

Si FetchDataFromExternalApiAsync() échoue (comme cela est intentionnellement configuré pour le faire avec une exception simulée), la politique de réessai capturera l'HttpRequestException, enregistrera la tentative de réessai et réessaiera l'opération.

La méthode FetchDataFromExternalApiAsync() simule l'extraction de données d'une API externe avec un délai et lance intentionnellement une HttpRequestException pour simuler des requêtes échouées.

Polly Retry (Comment cela fonctionne pour les développeurs) : Figure 4

Conclusion

En conclusion, la politique de relance de Polly s'avère inestimable pour gérer les erreurs transitoires et garantir la robustesse des applications C#. Sa flexibilité dans la configuration des tentatives de réessai, des délais et des conditions permet aux développeurs d'adapter les stratégies de résilience à des exigences spécifiques.

Que ce soit utilisé de manière indépendante ou en conjonction avec des bibliothèques comme IronPDF, Polly facilite la création d'applications qui se rétablissent agréablement de défaillances temporaires, améliorant ainsi l'expérience utilisateur et la fiabilité du logiciel.

En intégrant les capacités de réessai de Polly, les développeurs peuvent construire des systèmes plus résilients, capables de s'adapter et de récupérer des problèmes transitoires, améliorant ainsi la qualité et la fiabilité globales de leurs applications.

IronPDF est la meilleure bibliothèque PDF C# sur le marché, elle offre également une licence d'essai pour IronPDF avec des prix à partir de $749 USD.

Pour en savoir plus sur la conversion HTML en PDF avec IronPDF, visitez le Tutoriel de conversion HTML en PDF avec IronPDF.

Chaknith Bin
Ingénieur logiciel
Chaknith travaille sur IronXL et IronBarcode. Il possède une expertise approfondie en C# et .NET, aidant à améliorer le logiciel et à soutenir les clients. Ses idées issues des interactions avec les utilisateurs contribuent à de meilleurs produits, une documentation améliorée et une expérience globale enrichie.
< PRÉCÉDENT
C# iList (Comment ça marche pour les développeurs)
SUIVANT >
WebClient C# (Comment ça marche pour les développeurs)