まず、通常の処理
Httpリクエストをして結果を返すだけの処理。
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static async Task Main(string[] args)
{
if (await HttpGetAsync("https://www.microsoft.com/"))
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] リクエストは正常に処理されました。");
}
else
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] エラー");
}
}
private static async Task<bool> HttpGetAsync(string requestUri)
{
using var client = new HttpClient();
var response = await client.GetAsync(requestUri);
if (response.StatusCode == HttpStatusCode.OK)
{
return true;
}
else
{
return false;
}
}
}
}
至ってシンプルです。コレを実行しHttpリクエストが成功すると「リクエストは正常に処理されました。」が表示され、失敗すると「エラー」が表示されます。
成功時

失敗時

処理の修正
この処理に「エラーの場合3回までリトライしたい」「リトライ間隔は3秒間」という機能を盛り込みたい場合、愚直に処理を修正してもいいですが「あまりソースを変えたくない」「他にもリトライ機能を付けたい」となると、ちょっと手間だと思います。
なので、今回は「リトライ機能を持ったヘルパークラス」を作ることにします。
リトライ機能を持ったヘルパークラス
クラスはこんな感じになります。
using System;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public static class RepeatHelper
{
private const int MAX_REPEAT = 3;
private const int MILLISECONDS_TIMEOUT = 3000;
public static async Task<bool> RepeatProcessAsync(Func<string, Task<bool>> func, string requestUri)
{
var count = 0;
while (count < MAX_REPEAT)
{
if (count != 0)
{
// 初回以降インターバルを設定
await Task.Delay(MILLISECONDS_TIMEOUT);
}
if (await func(requestUri))
{
return true;
}
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] リクエストエラーのため、リトライ処理に入ります。");
count++;
}
return false;
}
}
}
使い方はこんな感じです。
//if (await HttpGetAsync("https://www.microsoft.com/"))
// ↓↓↓
// リトライヘルパークラスを使って処理をする。
if (await RetryHelper.RetryProcessAsync(HttpGetAsync, "https://www.microsoft.com/"))
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] リクエストは正常に処理されました。");
}
else
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] エラー");
}
RetryHelper.RetryProcessAsync に、関数と引数を渡して処理します。
このように、3秒間隔でリトライして3回失敗したらエラーになりました。

おわりに
処理を単純に修正するのもいいですが、直感的に分かりやすい処理を目指すのも有りかと思います。
まあ、人それぞれなので強要は出来ませんがね。