1
+ using System ;
2
+ using System . Threading . Tasks ;
3
+
4
+ namespace UtTestsExperimentalConsoleAppication . Utils ;
5
+
6
+ /// <summary>
7
+ /// Helper utilities for retrying flaky asynchronous operations.
8
+ /// </summary>
9
+ public static class RetryHelpers
10
+ {
11
+ /// <summary>
12
+ /// Repeatedly executes an asynchronous condition until it returns <c>true</c>
13
+ /// or the retry count is exhausted.
14
+ /// </summary>
15
+ /// <param name="condition">The asynchronous predicate to evaluate.</param>
16
+ /// <param name="maxAttempts">Maximum number of attempts.</param>
17
+ /// <param name="delayMs">Delay in milliseconds between attempts.</param>
18
+ /// <exception cref="TimeoutException">Thrown when the condition never evaluates to <c>true</c>.</exception>
19
+ public static async Task RetryAsync ( Func < Task < bool > > condition , int maxAttempts = 50 , int delayMs = 100 )
20
+ {
21
+ for ( int attempt = 0 ; attempt < maxAttempts ; attempt ++ )
22
+ {
23
+ if ( await condition ( ) )
24
+ {
25
+ return ;
26
+ }
27
+ await Task . Delay ( delayMs ) ;
28
+ }
29
+ throw new TimeoutException ( $ "Condition was not satisfied after { maxAttempts } attempts.") ;
30
+ }
31
+
32
+ /// <summary>
33
+ /// Repeatedly invokes an asynchronous action until it completes without
34
+ /// throwing an exception or the retry count is exceeded.
35
+ /// </summary>
36
+ /// <param name="action">The asynchronous action to execute.</param>
37
+ /// <param name="maxAttempts">Maximum number of attempts.</param>
38
+ /// <param name="delayMs">Delay in milliseconds between attempts.</param>
39
+ /// <exception cref="Exception">Rethrows the last exception when retries are exhausted.</exception>
40
+ public static async Task RetryAsync ( Func < Task > action , int maxAttempts = 50 , int delayMs = 100 )
41
+ {
42
+ Exception ? lastError = null ;
43
+ for ( int attempt = 0 ; attempt < maxAttempts ; attempt ++ )
44
+ {
45
+ try
46
+ {
47
+ await action ( ) ;
48
+ return ;
49
+ }
50
+ catch ( Exception ex )
51
+ {
52
+ lastError = ex ;
53
+ }
54
+ await Task . Delay ( delayMs ) ;
55
+ }
56
+ throw new TimeoutException ( $ "Action failed after { maxAttempts } attempts", lastError ) ;
57
+ }
58
+ }
0 commit comments