C#のリトライ制御を共通化
関わったプロジェクトでリトライ制御を共通化するクラスを作成してみたので、こちらに公開します。(結局プロジェクトでは使わなかったのでお釈迦になりましたが)
C#のリトライ記事と言えば既にこちらの記事とあちらの記事に技術情報が掲載されています。
簡単に実装したかったので、似たような方法ですがより簡便にしています。
※※多角的なテストはしていないので動作の保障はしません※※
RetryExecutor
using System;
namespace RetryExecutorNameSpace
{
/// <summary>
/// リトライ処理を行うクラス
/// </summary>
public class RetryExecutor
{
/// <summary>
/// 処理を実行する
/// 例外が発生した場合は指定秒数間隔でリトライする
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="retryFrequency">最大リトライ回数</param>
/// <param name="retryInterval">リトライ間隔</param>
/// <param name="action">処理</param>
/// <returns>処理結果</returns>
public static TResult Execute<TResult>(int retryFrequency, int retryInterval, Func<TResult> action)
{
//パラメータチェック
if (retryFrequency < 0)
{
//最大リトライ回数
throw new ArgumentOutOfRangeException("retryFrequency");
}
if (retryInterval < 0)
{
//リトライ間隔
throw new ArgumentOutOfRangeException("retryInterval");
}
if (action == null)
{
//処理
throw new ArgumentNullException("action");
}
/// <summary>
/// リトライ回数をカウントします
/// </summary>
int retryCount = 0;
while (true)
{
try
{
// メソッド
return action();
}
catch (Exception e)
{
//リトライが必要な処理で例外が発生した場合
//指定回数リトライ
if (retryCount++ < retryFrequency)
{
//最大リトライ回数に達していない場合
System.Threading.Thread.Sleep(retryInterval);
}
else
{
//最大リトライ回数に達した場合
throw e;
}
}
}
}
/// <summary>
/// 処理を実行する
/// 例外が発生した場合は指定秒数間隔でリトライする
/// </summary>
/// <param name="retryFrequency">最大リトライ回数</param>
/// <param name="retryInterval">リトライ間隔</param>
/// <param name="action">処理(戻り値無)</param>
public static void Execute(int retryFrequency, int retryInterval, Action action)
{
//パラメータチェック
if (retryFrequency < 0)
{
//最大リトライ回数
throw new ArgumentOutOfRangeException("retryFrequency");
}
if (retryInterval < 0)
{
//リトライ間隔
throw new ArgumentOutOfRangeException("retryInterval");
}
if (action == null)
{
//処理
throw new ArgumentNullException("action");
}
/// <summary>
/// リトライ回数をカウントします
/// </summary>
int retryCount = 0;
while (true)
{
try
{
action();
break;
}
catch (Exception e)
{
//リトライが必要な処理で例外が発生した場合
//指定回数リトライ
if (retryCount++ < retryFrequency)
{
//最大リトライ回数に達していない場合
System.Threading.Thread.Sleep(retryInterval);
}
else
{
//最大リトライ回数に達した場合
throw e;
}
}
}
}
}
}
使用例(戻り値なしメソッド)
// System.Console.WriteLine("Hello World!")をリトライ対象のメソッドに置き換えて、ご使用ください。
RetryExecutorNameSpace.RetryExecutor.Execute(4,1000, () => { System.Console.WriteLine("Hello World!"); });
RetryExecutorNameSpace.RetryExecutor.Execute
の引数の意味は下記の通りです。
引数:retryFrequency
・・・リトライ回数
引数:retryInterval
・・・リトライ間隔(ミリ秒)
引数:action
・・・リトライ対象のメソッド