Saltar al pie de página
.NET AYUDA

Polly Retry (Cómo Funciona para Desarrolladores)

Manejar fallas transitorias, tiempos de espera y excepciones de manera elegante es crucial para construir aplicaciones sólidas y resilientes. Polly es una popular biblioteca para .NET que proporciona capacidades de manejo de fallas transitorias y resiliencia. Entre sus muchas características, "retry" es una de las políticas más utilizadas.

En este artículo, profundizaremos en la política de reintento de Polly en C#, explorando su uso, opciones de configuración y proporcionando ejemplos de código prácticos. Además, utilizaremos la Biblioteca IronPDF para generación de PDF con el intento de reintento de Polly para generar un PDF de los resultados de solicitudes de formulario.

¿Qué es Polly Retry?

Polly Retry es una política proporcionada por la biblioteca Polly que permite a los desarrolladores reintentar automáticamente operaciones que podrían fallar debido a un error o fallas transitorias. Las fallas transitorias son errores temporales que ocurren debido a fallas de red, falta de disponibilidad del servicio u otros problemas transitorios.

Con la política de reintento de Polly, puedes definir reglas para reintentar operaciones, incluyendo el número máximo de reintentos, el retraso entre múltiples reintentos y las condiciones para volver a intentar una solicitud fallida. Esto ayuda a construir aplicaciones resilientes que puedan recuperarse de fallos temporales sin colapsar o causar interrupciones a los usuarios finales.

Cómo empezar con Polly Retry

Antes de profundizar en ejemplos de código, establezcamos un entendimiento básico de cómo instalar y configurar Polly en un proyecto C#.

Instalación de Polly

Puedes instalar Polly a través de la consola de administrador de paquetes NuGet usando el siguiente comando:

Install-Package Polly

O a través de .NET CLI:

dotnet add package Polly

Añadir declaraciones de uso de Polly

En tu archivo C#, incluye el espacio de nombres Polly:

using Polly;
using Polly;
$vbLabelText   $csharpLabel

Ejemplo básico de política de reintentos

Comencemos con un ejemplo simple donde reintentamos una operación que simula la obtención de datos de un servicio remoto. Configuraremos una política de reintento con un máximo de 3 reintentos y retraso fijo de tiempo de espera de 2 segundos entre reintentos.

using System;
using System.Net.Http;
using Polly;

namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Define a retry policy that handles HttpRequestException with a maximum of 3 retries
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify the exception type to handle
                .WaitAndRetry(
                    3, // Max retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Fixed retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });

            try
            {
                // Execute the action within the context of the retry policy
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }

        // Simulate fetching data that throws HttpRequestException
        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)
        {
            // Define a retry policy that handles HttpRequestException with a maximum of 3 retries
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify the exception type to handle
                .WaitAndRetry(
                    3, // Max retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Fixed retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });

            try
            {
                // Execute the action within the context of the retry policy
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }

        // Simulate fetching data that throws HttpRequestException
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
$vbLabelText   $csharpLabel

En este ejemplo:

  • Handle<HttpRequestException>() especifica que queremos manejar HttpRequestException y reintentar la operación si ocurre.
  • WaitAndRetry() configura la política de reintento con 3 reintentos y un retraso fijo de 2 segundos entre reintentos (duración máxima especificada).
  • El delegado onRetry registra un mensaje cuando ocurre un reintento.

Polly Retry (Cómo Funciona para Desarrolladores): Figura 1

Configuración avanzada de políticas de reintento

Retroceso exponencial

El retroceso exponencial es una estrategia de reintento popular donde el retraso entre solicitudes y reintentos aumenta exponencialmente. Polly proporciona una manera conveniente de implementar retroceso exponencial usando WaitAndRetry().

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)), // Exponential delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)), // Exponential delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
$vbLabelText   $csharpLabel

Polly Retry (Cómo Funciona para Desarrolladores): Figura 2

Retry con Circuit Breaker

Combinar reintento con un interruptor de circuito puede mejorar aún más la resiliencia al prevenir reintentos repetidos cuando un servicio está fallando constantemente. Polly te permite combinar políticas de reintento e interruptor de circuito fácilmente.

// Define a circuit breaker policy
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3, // Number of exceptions before breaking
        durationOfBreak: TimeSpan.FromSeconds(30), // Time circuit stays open
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });

// Define a retry policy
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2), // Fixed retry delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });

// Combine both policies into a single policy wrap
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
// Define a circuit breaker policy
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3, // Number of exceptions before breaking
        durationOfBreak: TimeSpan.FromSeconds(30), // Time circuit stays open
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });

// Define a retry policy
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3, // Max retry attempts
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2), // Fixed retry delay
        onRetry: (exception, timeSpan, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });

// Combine both policies into a single policy wrap
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
$vbLabelText   $csharpLabel

En este ejemplo:

  • CircuitBreaker() define una política de interruptor de circuito que se rompe después de 3 excepciones y permanece abierto durante 30 segundos.
  • Policy.Wrap() combina las políticas de interruptor de circuito y reintento en una sola política.

Polly Retry (Cómo Funciona para Desarrolladores): Figura 3

Introducción a IronPDF

IronPDF C# PDF Library Overview es una poderosa biblioteca C# que permite a los desarrolladores crear, editar y manipular documentos PDF dentro de sus aplicaciones .NET. Ya sea que necesites crear facturas, informes o cualquier otro tipo de documento PDF, IronPDF proporciona una API intuitiva que simplifica el proceso.

Con IronPDF, puedes convertir fácilmente HTML, CSS e incluso páginas web de ASP.NET a PDF, lo que la convierte en una herramienta versátil para una amplia gama de aplicaciones. Además, ofrece características avanzadas como agregar texto, imágenes y elementos interactivos a PDFs, así como aseguraros con encriptación y firmas digitales.

IronPDF destaca en la conversión de HTML a PDF, asegurando la preservación precisa de los diseños y estilos originales. Es perfecto para generar PDFs a partir de contenido basado en la web, como informes, facturas y documentación. IronPDF admite la conversión de archivos HTML, URLs y cadenas HTML en bruto en archivos PDF de alta calidad.

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");
    }
}
$vbLabelText   $csharpLabel

Polly Retry con IronPDF

Al trabajar con IronPDF, podría haber escenarios donde necesites obtener datos de fuentes externas o realizar operaciones complejas antes de generar un PDF.

En tales casos, podrías encontrar fallas transitorias o problemas temporales que podrían llevar al fallo en la generación de PDFs. Para manejar estas fallas transitorias de manera elegante, puedes usar Polly Retry en conjunto con IronPDF.

Instalación de IronPDF y Polly

Antes de comenzar, asegúrate de instalar el paquete NuGet de IronPDF en tu proyecto.

Install-Package IronPdf

Uso de Polly Retry con IronPDF

Veamos un ejemplo donde usamos Polly Retry para manejar fallas transitorias al generar un PDF usando IronPDF. En el siguiente ejemplo, simularemos la obtención de datos de una API externa y luego generaremos un PDF basado en esos datos. Usaremos Polly Retry para ejecutar la operación de obtención de datos en caso de fallos.

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)
        {
            // Define a retry policy with async capability
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify exception type to handle
                .WaitAndRetryAsync(
                    3, // Retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });

            // Execute the retry policy asynchronously
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync(); // Fetch data from an external source
                return GeneratePdfFromData(data); // Generate PDF using fetched data
            });

            pdf.SaveAs("GeneratedDocument.pdf");
        }

        // Simulate fetching data from an external API
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }

        // Generate PDF using IronPDF based on the fetched data
        static PdfDocument GeneratePdfFromData(string 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)
        {
            // Define a retry policy with async capability
            var retryPolicy = Policy
                .Handle<HttpRequestException>() // Specify exception type to handle
                .WaitAndRetryAsync(
                    3, // Retry attempts
                    retryAttempt => TimeSpan.FromSeconds(2), // Calculated retry delay
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });

            // Execute the retry policy asynchronously
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync(); // Fetch data from an external source
                return GeneratePdfFromData(data); // Generate PDF using fetched data
            });

            pdf.SaveAs("GeneratedDocument.pdf");
        }

        // Simulate fetching data from an external API
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            await Task.Delay(100); // Simulate delay
            throw new HttpRequestException("Failed to fetch data from external API");
        }

        // Generate PDF using IronPDF based on the fetched data
        static PdfDocument GeneratePdfFromData(string data)
        {
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
$vbLabelText   $csharpLabel

Este código C# demuestra cómo usar la biblioteca Polly para implementar políticas de reintento con IronPDF para generar un documento PDF. El método Main inicializa una política de reintento usando el método WaitAndRetryAsync de Polly.

Esta política especifica que debe manejar HttpRequestException y reintentar la operación hasta 3 veces con un retraso de 2 segundos entre el intento inicial y los reintentos. Si ocurre un fallo de reintento, se imprime un mensaje en la consola indicando el número de intento de reintento y el mensaje de la excepción.

Dentro del método Main, la lógica de la política de reintento se ejecuta de forma asíncrona usando retryPolicy.ExecuteAsync(). Dentro de esta ejecución, se encadenan dos operaciones asíncronas: FetchDataFromExternalApiAsync() y GeneratePdfFromData(data).

Si FetchDataFromExternalApiAsync() falla (ya que está configurado intencionadamente para hacerlo con una excepción simulada), la política de reintento capturará la HttpRequestException, registrará el intento de reintento y volverá a intentar la operación.

El método FetchDataFromExternalApiAsync() simula la obtención de datos de una API externa con un retraso y arroja intencionalmente una HttpRequestException para simular solicitudes fallidas.

Polly Retry (Cómo Funciona para Desarrolladores): Figura 4

Conclusión

En conclusión, la política de reintento de Polly resulta invaluable para manejar fallas transitorias y asegurar la robustez en aplicaciones C#. Su flexibilidad en la configuración de intentos de reintento, retrasos y condiciones permite a los desarrolladores adaptar estrategias de resiliencia a requisitos específicos.

Ya sea usado de manera independiente o en conjunto con bibliotecas como IronPDF, Polly facilita la creación de aplicaciones que se recuperan de manera elegante de fallos temporales, mejorando la experiencia del usuario y la fiabilidad del software.

Al integrar las capacidades de reintento de Polly, los desarrolladores pueden construir sistemas más resilientes que puedan adaptarse y recuperarse de problemas transitorios, mejorando en última instancia la calidad y fiabilidad de sus aplicaciones.

IronPDF es la mejor biblioteca de PDF en C# en el mercado, y también ofrece una licencia de prueba para IronPDF, los precios comienzan desde $799 USD.

Para aprender sobre la conversión de HTML a PDF usando IronPDF visita el siguiente Tutorial de Conversión de HTML a PDF con IronPDF.

Preguntas Frecuentes

¿Qué es Polly Retry en C#?

Polly Retry es una característica de la biblioteca Polly en C# que permite a los desarrolladores reintentar automáticamente operaciones que fallan debido a problemas temporales como fallos de red o indisponibilidad del servicio. Esto ayuda a construir aplicaciones resilientes manejando fallos transitorios de manera adecuada.

¿Cómo puedo implementar una política de reintento básica usando Polly?

Puede implementar una política de reintento básica en Polly manejando excepciones como HttpRequestException y configurando para reintentar un máximo de tres veces con un retraso fijo de dos segundos entre cada intento.

¿Cuál es la importancia del retroceso exponencial en Polly?

El retroceso exponencial en Polly se utiliza para aumentar exponencialmente el retraso entre reintentos, lo cual ayuda a reducir la carga en los servicios durante fallos. Esto se puede implementar utilizando el método WaitAndRetry de Polly, que calcula los retrasos basados en el crecimiento exponencial.

¿Cómo instalo Polly para un proyecto de C#?

Puede instalar Polly en un proyecto de C# utilizando la Consola del Administrador de Paquetes NuGet con el comando Install-Package Polly o a través de la CLI de .NET con dotnet add package Polly.

¿La política de reintento de Polly se puede combinar con otras estrategias de resiliencia?

Sí, Polly le permite combinar su política de reintento con otras estrategias de resiliencia, como un disyuntor, usando el método Policy.Wrap para mejorar la resiliencia de la aplicación y prevenir reintentos repetidos cuando un servicio falla constantemente.

¿Cómo puedo convertir HTML a PDF en C#?

Puede utilizar métodos de IronPDF como RenderHtmlAsPdf para convertir cadenas HTML en PDFs. IronPDF también soporta la conversión de archivos HTML y páginas web, incluyendo CSS, a formato PDF.

¿Por qué es importante la política de reintento de Polly para aplicaciones C#?

La política de reintento de Polly es crucial para manejar fallos transitorios en aplicaciones C#, asegurando robustez y mejorando la experiencia del usuario al permitir que el sistema se recupere de fallos temporales sin bloquearse.

¿Cómo se pueden implementar estrategias de reintento en un proceso de generación de PDF?

Al generar PDFs, se pueden implementar estrategias de reintento utilizando Polly para manejar fallos transitorios. Al integrar las capacidades de reintento de Polly con IronPDF, puede intentar operaciones de PDF múltiples veces en caso de problemas temporales de red o servicio.

¿Cómo instalo una biblioteca PDF de C# como IronPDF?

IronPDF se puede instalar a través del Administrador de Paquetes NuGet con el comando Install-Package IronPdf, permitiéndole crear, editar y manipular documentos PDF dentro de sus aplicaciones C#.

¿Cuáles son los beneficios de usar IronPDF para la generación de PDF?

IronPDF proporciona potentes características para crear y manipular documentos PDF en aplicaciones .NET. Soporta la conversión de HTML, CSS y páginas web a PDFs, añadir texto e imágenes, y asegurar documentos con encriptación.

Jacob Mellor, Director de Tecnología @ Team Iron
Director de Tecnología

Jacob Mellor es Director de Tecnología en Iron Software y un ingeniero visionario que lidera la tecnología PDF en C#. Como el desarrollador original detrás de la base de código central de Iron Software, ha moldeado la arquitectura de productos de la compañía desde ...

Leer más