[解決済み] 再試行ロジックの最もクリーンな記述方法とは?
2022-03-19 14:12:27
質問
時々、操作をあきらめる前に何度も再試行する必要があることがあります。 私のコードは次のようなものです。
int retries = 3;
while(true) {
try {
DoSomething();
break; // success!
} catch {
if(--retries == 0) throw;
else Thread.Sleep(1000);
}
}
これを一般的なリトライ関数に書き換えると、次のようになります。
TryThreeTimes(DoSomething);
C#で可能でしょうか? のコードはどうなるのでしょうか?
TryThreeTimes()
メソッドを使用できますか?
どのように解決するのですか?
同じ呼び出しを単純に再試行する包括的なcatch文は、一般的な例外処理メカニズムとして使用すると危険な場合があります。とはいえ、ここではどんなメソッドでも使えるラムダベースの再試行ラッパーを紹介します。再試行の回数と再試行のタイムアウトをパラメータにすることで、もう少し柔軟性を持たせることにしました。
public static class Retry
{
public static void Do(
Action action,
TimeSpan retryInterval,
int maxAttemptCount = 3)
{
Do<object>(() =>
{
action();
return null;
}, retryInterval, maxAttemptCount);
}
public static T Do<T>(
Func<T> action,
TimeSpan retryInterval,
int maxAttemptCount = 3)
{
var exceptions = new List<Exception>();
for (int attempted = 0; attempted < maxAttemptCount; attempted++)
{
try
{
if (attempted > 0)
{
Thread.Sleep(retryInterval);
}
return action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
throw new AggregateException(exceptions);
}
}
これで、このユーティリティ・メソッドを使って再試行ロジックを実行できるようになりました。
Retry.Do(() => SomeFunctionThatCanFail(), TimeSpan.FromSeconds(1));
または
Retry.Do(SomeFunctionThatCanFail, TimeSpan.FromSeconds(1));
または
int result = Retry.Do(SomeFunctionWhichReturnsInt, TimeSpan.FromSeconds(1), 4);
あるいは
async
をオーバーロードします。
関連
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み] .NETで文字列を改行で分割する最も簡単な方法とは?
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] C#で文字を繰り返し表示する最適な方法
-
[解決済み] ファイルが使用中であるかどうかを確認する方法はありますか?
-
[解決済み] INotifyPropertyChangedの実装 - より良い方法は存在するか?
-
[解決済み] アプリケーションフォルダのパスを取得する最適な方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] 1つ以上のエンティティで検証に失敗しました。詳細は'EntityValidationErrors'プロパティを参照してください [重複]。
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み】2つ(またはそれ以上)のリストを1つに統合する(C# .NETで
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】プロセスが実行されているかどうかを知るには?
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015