// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Threading; using ManagedCommon; namespace PowerDisplay.Common.Utils { /// /// Helper class for executing operations with retry logic. /// Provides a unified retry pattern for DDC/CI operations that may fail intermittently. /// public static class RetryHelper { /// /// Default delay between retry attempts in milliseconds. /// public const int DefaultRetryDelayMs = 100; /// /// Default maximum number of retry attempts. /// public const int DefaultMaxRetries = 3; /// /// Executes a synchronous operation with retry logic. /// /// The return type of the operation. /// The operation to execute. /// Predicate to determine if the result is valid. /// Maximum number of retry attempts (default: 3). /// Delay between retries in milliseconds (default: 100). /// Optional name for logging purposes. /// The result of the operation, or default if all retries failed. public static T? ExecuteWithRetry( Func operation, Func isValid, int maxRetries = DefaultMaxRetries, int delayMs = DefaultRetryDelayMs, string? operationName = null) { for (int attempt = 0; attempt < maxRetries; attempt++) { try { var result = operation(); if (isValid(result)) { if (attempt > 0 && !string.IsNullOrEmpty(operationName)) { Logger.LogDebug($"[Retry] {operationName} succeeded on attempt {attempt + 1}"); } return result; } if (attempt < maxRetries - 1) { if (!string.IsNullOrEmpty(operationName)) { Logger.LogWarning($"[Retry] {operationName} returned invalid result on attempt {attempt + 1}, retrying..."); } Thread.Sleep(delayMs); } } catch (Exception ex) { if (attempt < maxRetries - 1) { if (!string.IsNullOrEmpty(operationName)) { Logger.LogWarning($"[Retry] {operationName} failed on attempt {attempt + 1}: {ex.Message}, retrying..."); } Thread.Sleep(delayMs); } else { if (!string.IsNullOrEmpty(operationName)) { Logger.LogWarning($"[Retry] {operationName} failed after {maxRetries} attempts: {ex.Message}"); } } } } if (!string.IsNullOrEmpty(operationName)) { Logger.LogWarning($"[Retry] {operationName} failed after {maxRetries} attempts"); } return default; } } }