
Polly Retry (jak to działa dla programistów)
Płynne radzenie sobie z przejściowymi błędami, limitami czasu i wyjątkami ma kluczowe znaczenie przy tworzeniu solidnych i odpornych aplikacji. Polly to popularna biblioteka .NET, która zapewnia odporność i możliwości obsługi błędów przejściowych. Spośród wielu funkcji "ponowna próba" jest jedną z najczęściej stosowanych zasad.
W tym artykule zgłębimy politykę powtórzeń Polly w C#, badając jej użycie, opcje konfiguracji oraz dostarczając praktyczne przykłady kodu. Ponadto użyjemy biblioteki IronPDF do generowania plików PDF wraz z funkcją ponownej próby Polly, aby wygenerować plik PDF zawierający wyniki żądania formularza.
Czym jest Polly Retry?
Polly Retry to funkcja biblioteki Polly, która umożliwia programistom automatyczne ponawianie operacji, które mogą zakończyć się niepowodzeniem z powodu błędu lub przejściowych awarii. Usterki przejściowe to tymczasowe błędy, które występują z powodu zakłóceń sieciowych, niedostępności usług lub innych przejściowych problemów.
Dzięki polityce ponownych prób Polly można zdefiniować reguły dotyczące ponawiania operacji, w tym maksymalną liczbę ponownych prób, opóźnienie między kolejnymi próbami oraz warunki ponownego wysłania nieudanego żądania. Pomaga to w tworzeniu odpornych aplikacji, które mogą odzyskać sprawność po tymczasowych awariach bez ulegania awarii lub powodowania zakłóceń dla użytkowników końcowych.
Pierwsze kroki z Polly Retry
Zanim przejdziemy do przykładów kodu, zapoznajmy się z podstawowymi informacjami na temat instalacji i konfiguracji Polly w projekcie C#.
Instalacja Polly
Możesz zainstalować Polly za pomocą konsoli menedżera pakietów NuGet, używając następującego polecenia:
Lub za pomocą .NET CLI:
Dodawanie Polly za pomocą instrukcji
W pliku C# należy dołączyć przestrzeń nazw Polly:
using Polly;Imports PollyPrzykład podstawowej polityki ponownych prób
Zacznijmy od prostego przykładu, w którym ponawiamy operację symulującą pobieranie danych ze zdalnej usługi. Skonfigurujemy politykę ponawiania prób z maksymalnie 3 próbami i stałym opóźnieniem wynoszącym 2 sekundy między próbami.
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");
}
}
}Imports System
Imports System.Net.Http
Imports Polly
Namespace PollyRetryExample
Public Class Program
Public Shared Sub Main(ByVal args() As String)
' Define a retry policy that handles HttpRequestException with a maximum of 3 retries
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
' Execute the action within the context of the retry policy
retryPolicy.Execute(Sub()
FetchDataFromRemoteService()
End Sub)
Catch ex As Exception
Console.WriteLine("Failed after 3 retries: {0}", ex.Message)
End Try
End Sub
' Simulate fetching data that throws HttpRequestException
Public Shared Sub FetchDataFromRemoteService()
Throw New HttpRequestException("Failed to fetch data from remote service")
End Sub
End Class
End NamespaceW tym przykładzie:
Handle<HttpRequestException>()okresla, ze chcemy obsluzycHttpRequestExceptioni ponowic operacje, jesli wystapi.WaitAndRetry()konfiguruje polityke ponawiania z 3 próbami i ustalonym opoznieniem 2 sekund miedzy próbami (okreslona maksymalna dlugosc trwania).onRetrydelegat rejestruje wiadomosc, gdy wystapi ponowienie.

Zaawansowana konfiguracja zasad ponawiania prób
Wykładniczy backoff
Wykładnicze opóźnianie (exponential backoff) to popularna strategia ponawiania prób, w której opóźnienie między żądaniami a ponownymi próbami rośnie wykładniczo. Polly zapewnia wygodny sposob implementacji wykładniczego wycofywania przy użyciu 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}");
});Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(Math.Pow(2, attempt)), onRetry:= Sub(exception, timeSpan, retryCount, context)
Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
Ponów próbę z Circuit Breaker
Połączenie ponownej próby z mechanizmem typu circuit breaker może dodatkowo zwiększyć odporność, zapobiegając powtarzającym się próbom w przypadku ciągłych awarii usługi. Polly pozwala w łatwy sposób łączyć zasady ponownych prób i wyłączników obwodów.
// 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
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)
' Define a retry policy
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(2), onRetry:= Sub(exception, timeSpan, retryCount, context)
Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
' Combine both policies into a single policy wrap
Dim policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy)W tym przykładzie:
CircuitBreaker()okresla polityke wylacznika obwodu, ktora przerywa po 3 wyjątkach i pozostaje otwarta przez 30 sekund.Policy.Wrap()laczy polityki wylacznika obwodu i ponawiania w jedna polityke.

Wprowadzenie do IronPDF
IronPDF C# PDF Library Overview to potężna biblioteka C#, która pozwala programistom tworzyć, edytować i manipulować dokumentami PDF w ramach ich aplikacji .NET. Niezależnie od tego, czy potrzebujesz tworzyć faktury, raporty czy jakikolwiek inny rodzaj dokumentu PDF, IronPDF zapewnia intuicyjny interfejs API, który upraszcza ten proces.
Dzięki IronPDF można łatwo konwertować strony HTML, CSS, a nawet ASP.NET do formatu PDF, co czyni go wszechstronnym narzędziem do szerokiego zakresu zastosowań. Ponadto oferuje zaawansowane funkcje, takie jak dodawanie tekstu, obrazów i elementów interaktywnych do plików PDF, a także zabezpieczanie ich za pomocą szyfrowania i podpisów cyfrowych.
IronPDF doskonale radzi sobie z konwersją HTML do PDF, zapewniając precyzyjne zachowanie oryginalnych układów i stylów. Idealnie nadaje się do generowania plików PDF z treści internetowych, takich jak raporty, faktury i dokumentacja. IronPDF obsługuje konwersję plików HTML, adresów URL i surowych ciągów znaków HTML na wysokiej jakości pliki 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 ClassPolly Retry z IronPDF
Podczas pracy z IronPDF mogą wystąpić sytuacje, w których konieczne będzie pobranie danych ze źródeł zewnętrznych lub wykonanie złożonych operacji przed wygenerowaniem pliku PDF.
W takich przypadkach mogą wystąpić przejściowe usterki lub tymczasowe problemy, które mogą prowadzić do niepowodzeń w generowaniu plików PDF. Aby płynnie radzić sobie z tymi przejściowymi błędami, można użyć funkcji Polly Retry w połączeniu z IronPDF.
Instalacja IronPDF i Polly
Przed rozpoczęciem pracy upewnij się, że w swoim projekcie zainstalowałeś pakiet IronPDF NuGet.
Korzystanie z funkcji Polly Retry w IronPDF
Przyjrzyjmy się przykładowi, w którym używamy Polly Retry do obsługi przejściowych błędów podczas generowania pliku PDF za pomocą IronPDF. W poniższym przykładzie zasymulujemy pobieranie danych z zewnętrznego API, a następnie wygenerujemy plik PDF na podstawie tych danych. Uzyjemy Polly Retry do wykonania operacji pobierania danych w przypadku awarii.
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);
}
}
}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
' Define a retry policy with async capability
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)
' Execute the retry policy asynchronously
Dim pdf = Await retryPolicy.ExecuteAsync(Async Function()
Dim data = Await FetchDataFromExternalApiAsync() ' Fetch data from an external source
Return GeneratePdfFromData(data) ' Generate PDF using fetched data
End Function)
pdf.SaveAs("GeneratedDocument.pdf")
End Function
' Simulate fetching data from an external API
Private Shared Async Function FetchDataFromExternalApiAsync() As Task(Of String)
Await Task.Delay(100) ' Simulate delay
Throw New HttpRequestException("Failed to fetch data from external API")
End Function
' Generate PDF using IronPDF based on the fetched data
Private Shared Function GeneratePdfFromData(ByVal data As String) As PdfDocument
Dim htmlContent = "<html><body><h1>Data: " & data & "</h1></body></html>"
Dim renderer = New ChromePdfRenderer()
Return renderer.RenderHtmlAsPdf(htmlContent)
End Function
End Class
End NamespaceTen kod w języku C# pokazuje, jak używać biblioteki Polly do wdrażania zasad ponownych prób z IronPDF w celu wygenerowania dokumentu PDF. Metoda Main inicjalizuje polityke ponawiania, korzystajac z metody Polly WaitAndRetryAsync.
Ta polityka okresla, ze powinna obsluzyc HttpRequestException i ponowic operacje do 3 razy z opoznieniem 2 sekund pomiedzy poczatkową próba a ponownymi próbami. W przypadku niepowodzenia ponownej próby na konsoli wyświetlany jest komunikat wskazujący numer próby ponownej oraz komunikat o wyjątku.
Wewnatrz metody Main logika polityki ponawiania jest wykonywana asynchronicznie za pomocą retryPolicy.ExecuteAsync(). W trakcie tego wykonania dwa asynchroniczne operacje sa polaczone: FetchDataFromExternalApiAsync() oraz GeneratePdfFromData(data).
Jesli FetchDataFromExternalApiAsync() zawiedzie (jak jest to celowo ustawione przy przykladzie symulowanej wyjatku), polityka ponawiania przechwyci HttpRequestException, zarejestruje probe ponowienia i ponowi operacje.
Metoda FetchDataFromExternalApiAsync() symuluje pobieranie danych z zewnetrznego API z opoznieniem i celowo zglasza HttpRequestException w celu symulacji nieudanych zadan.

Wnioski
Podsumowując, polityka ponownych prób Polly okazuje się nieoceniona w radzeniu sobie z przejściowymi błędami i zapewnianiu niezawodności aplikacji C#. Elastyczność w konfiguracji prób ponownego wykonania, opóźnień i warunków pozwala programistom dostosować strategie odporności do konkretnych wymagań.
Niezależnie od tego, czy jest używany samodzielnie, czy w połączeniu z bibliotekami takimi jak IronPDF, Polly ułatwia tworzenie aplikacji, które płynnie radzą sobie z tymczasowymi awariami, poprawiając komfort użytkowania i niezawodność oprogramowania.
Dzięki integracji funkcji ponownego wykonywania operacji Polly programiści mogą tworzyć bardziej odporne systemy, które potrafią dostosowywać się do przejściowych problemów i odzyskiwać sprawność, co ostatecznie poprawia ogólną jakość i niezawodność ich aplikacji.
IronPDF to najlepsza biblioteka PDF w C# na rynku, oferuje równiez licencje probna dla IronPDF, a ceny zaczynaja sie od $999 USD.
Aby dowiedzieć się więcej o konwersji HTML do PDF przy użyciu IronPDF, odwiedź następujący samouczek dotyczący konwersji HTML do PDF w IronPDF.

Jacob Mellor jest Chief Technology Officer w Iron Software i wizjonerskim inżynierem, pionierem technologii C# PDF. Jako pierwotny deweloper głównej bazy kodowej Iron Software, kształtuje architekturę produktów firmy od jej początku, przekształcając ją wspólnie z CEO Cameron Rimington w firmę liczącą ponad 50 osób, obsługującą NASA, Teslę i światowe agencje rządowe.
Powiązane artykuły


