Pruebas en un entorno real
Pruebe en producción sin marcas de agua.
Funciona donde lo necesites.
Gestionar los fallos transitorios, los tiempos de espera y las excepciones con elegancia es crucial para crear aplicaciones robustas y resistentes. Polly es una popular librería .NET que proporciona capacidades de resiliencia y gestión de fallos transitorios. Entre sus muchas funciones, "reintentar" es una de las políticas más utilizadas.
En este artículo, profundizaremos enPolítica de reintentos de Polly en C#y las opciones de configuración, así como ejemplos prácticos de código. Además, utilizaremosBiblioteca IronPDF para la generación de PDF con el intento de Polly Retry para generar un PDF con los resultados de la solicitud del formulario.
Polly Retry es una política proporcionada por la librería Polly que permite a los desarrolladores reintentar automáticamente operaciones que puedan fallar debido a un error o fallos transitorios. Los fallos transitorios son errores temporales que se producen debido a fallos de la red, indisponibilidad del servicio u otros problemas transitorios.
Con la política de reintentos de Polly, puede definir reglas para reintentar operaciones, incluido el número máximo de reintentos, el retraso entre varios reintentos y las condiciones para reintentar una solicitud fallida. Esto ayuda a crear aplicaciones resistentes que pueden recuperarse de fallos temporales sin bloquearse ni causar interrupciones a los usuarios finales.
Antes de sumergirnos en los ejemplos de código, vamos a establecer una comprensión básica de cómo instalar y configurar Polly en un proyecto C#.
Puede instalar Polly a través de la Consola del Gestor de Paquetes NuGet utilizando el siguiente comando:
Install-Package Polly
Install-Package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package Polly
O a través de .NET CLI:
dotnet add package Polly
dotnet add package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package Polly
En su archivo C#, incluya el espacio de nombres Polly:
using Polly;
using Polly;
Imports Polly
Empecemos con un ejemplo sencillo en el que reintentamos una operación que simula la obtención de datos de un servicio remoto. Configuraremos una política de reintentos con un máximo de 3 reintentos y un tiempo de espera fijo de 2 segundos entre reintentos.
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
En este ejemplo:
HttpRequestException
y reintentar la operación si ocurre.EsperarYRetener()
configura la política de reintentos con 3 reintentos y un retardo fijo de 2 segundos entre reintentos.(duración máxima especificada).el delegado onRetry
registra un mensaje cuando se produce un reintento.
El backoff exponencial es una popular estrategia de reintentos en la que el retardo entre peticiones y reintentos aumenta exponencialmente. Polly proporciona una manera conveniente de implementar el backoff exponencial usando 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)
Combinar el reintento con un disyuntor puede mejorar aún más la resiliencia al evitar repetidos reintentos cuando un servicio falla constantemente. Polly le permite combinar fácilmente las políticas de reintento y de disyuntor.
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)
En este ejemplo:
Policy.Wrap()
combina las políticas de interrupción y reintento en una única política.
Descripción general de la biblioteca PDF IronPDF C# es una potente biblioteca C# que permite a los desarrolladores crear, editar y manipular documentos PDF dentro de sus aplicaciones .NET. Tanto si necesita crear facturas, informes o cualquier otro tipo de documento PDF, IronPDF proporciona una API intuitiva que simplifica el proceso.
Con IronPDF, puede convertir fácilmente páginas web HTML, CSS e incluso ASP.NET a PDF, lo que la convierte en una herramienta versátil para una amplia gama de aplicaciones. Además, ofrece funciones avanzadas como añadir texto, imágenes y elementos interactivos a los PDF, así como protegerlos con cifrado y firmas digitales.
Al trabajar con IronPDF, puede haber situaciones en las que necesite obtener datos de fuentes externas o realizar operaciones complejas antes de generar un PDF.
En estos casos, es posible que se produzcan fallos transitorios o problemas temporales que podrían provocar fallos en la generación de PDF. Para gestionar estos fallos transitorios con elegancia, puede utilizar Polly Retry junto con IronPDF.
Antes de empezar, asegúrese de instalar el paquete IronPDF NuGet en su proyecto.
Install-Package IronPdf
Veamos un ejemplo en el que utilizamos Polly Retry para gestionar fallos transitorios al generar un PDF utilizando IronPDF. En el siguiente ejemplo, simularemos la obtención de datos de una API externa y la posterior generación de un PDF basado en esos datos. Utilizaremos 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)
{
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
Este código C# demuestra cómo utilizar 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 reintentos utilizando el método WaitAndRetryAsync
de Polly.
Esta política especifica que debe manejar HttpRequestException
y reintentar la operación hasta 3 veces con un retardo de 2 segundos entre el intento inicial y los reintentos. Si se produce un fallo de reintento, se imprime un mensaje en la consola indicando el número de intento de reintento y el mensaje de excepción.
Dentro del método Main
, la lógica de la política de reintentos se ejecuta de forma asíncrona utilizando retryPolicy.ExecuteAsync()
. Dentro de esta ejecución, se encadenan dos operaciones asíncronas: FetchDataFromExternalApiAsync()
y GeneratePdfFromData(datos)
.
Si FetchDataFromExternalApiAsync()
falla(como está intencionadamente configurado para hacer con una excepción simulada)la política de reintento capturará la HttpRequestException
, registrará el intento de reintento y reintentará la operación.
La función FetchDataFromExternalApiAsync()simula la obtención de datos de una API externa con un retraso y lanza intencionadamente una
HttpRequestException` para simular peticiones fallidas.
En conclusión, la política de reintentos de Polly resulta inestimable para gestionar fallos transitorios y garantizar la robustez de las aplicaciones C#. Su flexibilidad a la hora de configurar los intentos de reintento, los retrasos y las condiciones permite a los desarrolladores adaptar las estrategias de resistencia a requisitos específicos.
Tanto si se utiliza de forma independiente como en combinación con bibliotecas comoIronPDF, Polly facilita la creación de aplicaciones que se recuperan con elegancia de fallos temporales, mejorando la experiencia del usuario y la fiabilidad del software.
Al integrar las funciones de reintento de Polly, los desarrolladores pueden crear sistemas más resistentes que pueden adaptarse y recuperarse de problemas transitorios, mejorando en última instancia la calidad y fiabilidad general de sus aplicaciones.
IronPDF es la mejor librería PDF en C# del mercado, además ofrece unlicencia de prueba para IronPDF precios a partir de $749 USD.
Para obtener más información sobre la conversión de HTML a PDF con IronPDF, visite la siguiente página webTutorial de conversión de HTML a PDF de IronPDF.
9 productos API .NET para sus documentos de oficina