.NET ヘルプ

開発者向けのPolly Retry (その仕組み)

公開済み 2024年6月6日
共有:

一時的な障害、タイムアウト、および例外を巧みに処理することは、堅牢で回復力のあるアプリケーションを構築する上で非常に重要です。 Pollyは、回復力および一過性の障害処理機能を提供する人気のある.NETライブラリです。 その多くの機能の中で、「再試行」は最も広く使用されているポリシーの一つです。

この記事では、C#におけるPollyのリトライポリシーその使用法、設定オプションを探索し、実用的なコード例を提供します。 また、私たちは使用しますPDF生成のためのIronPDFライブラリPolly Retryを使用してフォームリクエストの結果のPDF生成を試みます。

Polly Retryとは何ですか?

Polly再試行は、エラーや一時的な障害によって失敗する可能性のある操作を自動的に再試行することを可能にするPollyライブラリによって提供されるポリシーです。 過渡的な障害とは、ネットワークの不具合、サービスの利用不可、または他の一時的な問題によって発生する一時的なエラーのことです。

Pollyの再試行ポリシーを使用すると、操作を再試行するためのルールを定義できます。これには、最大再試行回数、複数の再試行間の遅延、および失敗したリクエストを再試行するための条件が含まれます。これにより、一時的な障害からクラッシュせず、またはエンドユーザーに混乱を引き起こすことなくアプリケーションが回復できるような、高い耐障害性を持つアプリケーションを構築することが可能になります。

Polly Retryの使用を開始する

コード例に進む前に、C#プロジェクトでPollyをインストールおよび設定する基本的な理解を深めましょう。

Pollyのインストール

次のコマンドを使用して、NuGetパッケージマネージャーコンソール経由でPollyをインストールできます。

Install-Package Polly
Install-Package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package Polly
VB   C#

または .NET CLI 経由:

dotnet add package Polly
dotnet add package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package Polly
VB   C#

ポリーのusingステートメントを追加

C#ファイルにPolly名前空間を含めてください:

using Polly;
using Polly;
Imports Polly
VB   C#

基本リトライポリシーの例

シンプルな例から始めましょう。リモートサービスからデータをフェッチする操作をシミュレートする際にリトライ(再試行)を行います。最大3回のリトライと、リトライの間に2秒の固定タイムアウトの遅延を設定するリトライポリシーを設定します。

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
VB   C#

この例では:

  • ハンドル<HttpRequestException>()HttpRequestException を処理し、発生した場合に操作を再試行することを指定します。
  • `WaitAndRetry(待機して再試行)()リトライ ポリシーを3回のリトライとリトライ間の2秒の固定遅延で設定します。(指定された最大期間).
  • onRetryデリゲートはリトライが発生したときにメッセージをログに記録します。

    Pollyリトライ(開発者向けの操作方法): 図1

高度なリトライポリシー構成

指数バックオフ

指数バックオフは、リクエストと再試行の間の遅延が指数関数的に増加する一般的な再試行戦略です。 Pollyは、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)
VB   C#

ポリリ トライ(開発者向けの動作方法):図2

サーキットブレーカーで再試行

リトライをサーキットブレーカーと組み合わせることで、サービスが常に失敗している場合にリトライを繰り返すことを防ぎ、回復力をさらに向上させることができます。 Pollyを使用すると、リトライポリシーとサーキットブレーカーポリシーを簡単に組み合わせることができます。

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)
VB   C#

この例では:

  • 回路遮断器()`は、3回の例外が発生した後にブレークし、30秒間オープン状態を維持するサーキットブレーカーポリシーを定義します。
  • Policy.Wrap() サーキットブレーカーと再試行ポリシーを単一のポリシーに統合します。

    ポーリーリトライ(開発者のための仕組み):図3

IronPDFの紹介

IronPDF C# PDFライブラリの概要は、開発者が.NETアプリケーション内でPDFドキュメントを作成、編集、操作することを可能にする強力なC#ライブラリです。 請求書、レポート、その他のPDFドキュメントを作成する必要がある場合、IronPDFはプロセスを簡素化する直感的なAPIを提供します。

IronPDF を使用すると、HTML、CSS、さらには ASP.NET ウェブページを簡単に PDF に変換でき、さまざまな用途に適した多機能ツールになります。 さらに、PDFにテキストや画像、インタラクティブな要素を追加するなどの高度な機能を提供し、暗号化やデジタル署名でセキュリティを強化することもできます。

IronPDFでのPollyリトライ

IronPDFを使用する際、PDFを生成する前に外部ソースからデータを取得したり複雑な操作を実行したりする必要があるシナリオがあるかもしれません。

そのような場合、一時的な障害や一時的な問題が発生し、PDF生成が失敗する可能性があります。 これらの一時的な障害を優雅に処理するために、Polly RetryをIronPDFと組み合わせて使用できます。

IronPDFとPollyのインストール

始める前に、プロジェクトにIronPDF NuGetパッケージをインストールしてください。

Install-Package IronPdf

IronPDFでPollyリトライを使用する

ポリーリトライを使用して一時的な障害を処理しながら、IronPDFを使用してPDFを生成する例を見てみましょう。 以下の例では、外部APIからデータを取得し、そのデータに基づいてPDFを生成します。 失敗した場合に備えてデータ取得操作を実行するために、PollyのRetryを使用します。

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
VB   C#

次のC#コードは、Pollyライブラリを使用してリトライポリシーを実装し、IronPDFでPDFドキュメントを生成する方法を示しています。 Main メソッドは、Polly の WaitAndRetryAsync メソッドを使用してリトライポリシーを初期化します。

このポリシーは、HttpRequestExceptionを処理し、最初の試行と再試行の間に2秒の遅延を設けて、操作を最大3回まで再試行することを指定しています。 再試行に失敗した場合、再試行の試行回数と例外メッセージを示すメッセージがコンソールに出力されます。

Mainメソッド内で、リトライポリシーのロジックはretryPolicy.ExecuteAsyncを使用して非同期に実行されます。(). この実行の中で、2つの非同期処理がチェーンされています:FetchDataFromExternalApiAsync() と GeneratePdfFromData(データ)`.

外部APIからデータを非同期に取得します (FetchDataFromExternalApiAsync)()失敗します(シミュレートされた例外で意図的に設定されるように)リトライポリシーはHttpRequestException` をキャッチし、リトライの試行をログに記録し、操作を再試行します。

外部APIからデータを取得するための関数であるFetchDataFromExternalApiAsync()メソッドは遅延を伴って外部APIからデータを取得するシミュレーションを行い、意図的にHttpRequestExceptionをスローしてリクエストの失敗をシミュレーションします。

Polly リトライ(開発者向けの動作内容):図4

結論

結論として、Pollyのリトライポリシーは一時的な障害を処理し、C#アプリケーションの堅牢性を確保するために非常に貴重です。 再試行の試行回数、遅延、および条件を設定する柔軟性により、開発者は特定の要件に応じて耐障害性戦略をカスタマイズできます。

独立して使用する場合でも、またはライブラリと組み合わせて使用する場合でもIronPDFPollyは、アプリケーションが一時的な障害から優雅に回復し、ユーザーエクスペリエンスとソフトウェアの信頼性を向上させることを支援します。

Pollyのリトライ機能を統合することで、開発者は一時的な問題に適応し回復できる、より強靭なシステムを構築することができ、最終的にアプリケーションの全体的な品質や信頼性を向上させることができます。

IronPDFは市場で最も優れたC# PDFライブラリであり、提供しています。IronPDFトライアルライセンス価格は $749 USDから始まります。

HTMLからPDFへの変換について学ぶために、IronPDFを使用するには、以下を参照してください。IronPDF HTMLからPDFへの変換チュートリアル.

< 以前
C# iList(開発者向けの動作方法)
次へ >
WebClient C#(開発者向けの動作方法)