ResilientUtils.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. namespace MeloongCore;
  2. public static class ResilientUtils {
  3. /// <summary>
  4. /// 在抛出异常时,延迟并自动重试。
  5. /// </summary>
  6. public static void Retry(Action action, int maxAttempts = 2, int delayMs = 200, [CallerMemberName] string caller = "")
  7. => RetryOn<Exception>(action, maxAttempts, delayMs, caller);
  8. /// <summary>
  9. /// 在抛出特定异常时,延迟并自动重试。
  10. /// </summary>
  11. public static void RetryOn<TException>(Action action, int maxAttempts = 2, int delayMs = 200, [CallerMemberName] string caller = "") where TException : Exception {
  12. int attempt = 0;
  13. while (true) {
  14. try {
  15. action();
  16. return; // 成功则退出
  17. } catch (TException ex) {
  18. attempt++;
  19. if (attempt >= maxAttempts) throw; // 超过最大尝试次数
  20. Logger.Warn(ex, $"{caller} 第 {attempt} 次尝试失败,将在 {delayMs}ms 后重试");
  21. Thread.Sleep(delayMs);
  22. }
  23. }
  24. }
  25. /// <summary>
  26. /// 在抛出异常时,延迟并自动重试。
  27. /// </summary>
  28. public static void Retry<TOut>(Func<TOut> func, int maxAttempts = 2, int delayMs = 200, [CallerMemberName] string caller = "")
  29. => RetryOn<Exception, TOut>(func, maxAttempts, delayMs, caller);
  30. /// <summary>
  31. /// 在抛出特定异常时,延迟并自动重试。
  32. /// </summary>
  33. public static TOut RetryOn<TException, TOut>(Func<TOut> func, int maxAttempts = 2, int delayMs = 200, [CallerMemberName] string caller = "") where TException : Exception {
  34. int attempt = 0;
  35. while (true) {
  36. try {
  37. return func(); // 成功则退出
  38. } catch (TException ex) {
  39. attempt++;
  40. if (attempt >= maxAttempts) throw; // 超过最大尝试次数
  41. Logger.Warn(ex, $"{caller} 第 {attempt} 次尝试失败,将在 {delayMs}ms 后重试");
  42. Thread.Sleep(delayMs);
  43. }
  44. }
  45. }
  46. }