diff --git a/src/c#/GeneralUpdate.Drivelution/Abstractions/Configuration/DriverUpdateOptions.cs b/src/c#/GeneralUpdate.Drivelution/Abstractions/Configuration/DriverUpdateOptions.cs
index 2ac883f9..c1f7b5cb 100644
--- a/src/c#/GeneralUpdate.Drivelution/Abstractions/Configuration/DriverUpdateOptions.cs
+++ b/src/c#/GeneralUpdate.Drivelution/Abstractions/Configuration/DriverUpdateOptions.cs
@@ -62,6 +62,12 @@ public class DrivelutionOptions
///
public int BackupsToKeep { get; set; } = 5;
+ ///
+ /// 重试时是否使用指数退避(每次重试延迟翻倍)
+ /// Whether to use exponential backoff for retries (doubles delay each retry)
+ ///
+ public bool UseExponentialBackoff { get; set; } = false;
+
///
/// 信任的证书指纹列表(用于签名验证)
/// Trusted certificate thumbprints (for signature validation)
diff --git a/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/BaseDriverUpdater.cs b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/BaseDriverUpdater.cs
new file mode 100644
index 00000000..029ab0fd
--- /dev/null
+++ b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/BaseDriverUpdater.cs
@@ -0,0 +1,444 @@
+using GeneralUpdate.Common.Shared;
+using GeneralUpdate.Drivelution.Abstractions;
+using GeneralUpdate.Drivelution.Abstractions.Configuration;
+using GeneralUpdate.Drivelution.Abstractions.Exceptions;
+using GeneralUpdate.Drivelution.Abstractions.Models;
+
+namespace GeneralUpdate.Drivelution.Core.Pipeline;
+
+///
+/// Abstract base class for platform-specific driver updaters.
+/// Provides the unified update pipeline with retry, timeout, progress reporting, and automatic rollback.
+/// Subclasses only need to implement .
+///
+public abstract class BaseDriverUpdater : IGeneralDrivelution
+{
+ ///
+ /// Driver validator instance.
+ ///
+ protected readonly IDriverValidator _validator;
+
+ ///
+ /// Driver backup instance.
+ ///
+ protected readonly IDriverBackup _backup;
+
+ private readonly DrivelutionOptions _options;
+ private readonly RetryPolicy _retryPolicy;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Driver validator for integrity, signature, and compatibility checks.
+ /// Driver backup manager.
+ /// Configuration options (optional).
+ protected BaseDriverUpdater(
+ IDriverValidator validator,
+ IDriverBackup backup,
+ DrivelutionOptions? options = null)
+ {
+ _validator = validator ?? throw new ArgumentNullException(nameof(validator));
+ _backup = backup ?? throw new ArgumentNullException(nameof(backup));
+ _options = options ?? new DrivelutionOptions();
+ _retryPolicy = RetryPolicy.FromOptions(_options);
+ }
+
+ // ─── IGeneralDrivelution Implementation ────────────────────────────
+
+ ///
+ public async Task UpdateAsync(
+ DriverInfo driverInfo,
+ UpdateStrategy strategy,
+ CancellationToken cancellationToken = default)
+ {
+ var result = new UpdateResult
+ {
+ StartTime = DateTime.UtcNow,
+ Status = UpdateStatus.NotStarted
+ };
+
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Starting driver update for {driverInfo.Name} v{driverInfo.Version}");
+
+ var context = new PipelineContext(driverInfo, strategy, result);
+
+ // Linked token: user cancellation + timeout
+ var timeoutSeconds = strategy.TimeoutSeconds > 0
+ ? strategy.TimeoutSeconds
+ : _options.DefaultTimeoutSeconds;
+
+ using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds));
+ using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
+ cancellationToken, timeoutCts.Token);
+
+ try
+ {
+ GeneralTracer.Info($"Starting driver update: {driverInfo.Name} v{driverInfo.Version} " +
+ $"(timeout={timeoutSeconds}s, retries={_retryPolicy.MaxRetries})");
+
+ var steps = GetPipelineSteps(strategy)
+ .Where(s => s.ShouldExecute(context))
+ .ToList();
+
+ var totalSteps = steps.Count;
+ int stepIndex = 0;
+ PipelineResult? lastStepResult = null;
+
+ foreach (var step in steps)
+ {
+ stepIndex++;
+ OnStepStarted?.Invoke(step.StepName);
+ ReportProgress((int)((float)(stepIndex - 1) / totalSteps * 100), $"Running: {step.StepName}");
+
+ // Execute step with retry on transient failures
+ try
+ {
+ lastStepResult = await _retryPolicy.ExecuteAsync(
+ ct => step.ExecuteAsync(context, ct),
+ linkedCts.Token);
+ }
+ catch (OperationCanceledException)
+ {
+ result.Success = false;
+ result.Status = UpdateStatus.Failed;
+ result.Error = new ErrorInfo
+ {
+ Type = ErrorType.Timeout,
+ Code = "ERR_TIMEOUT",
+ Message = $"Driver update timed out after {timeoutSeconds} seconds.",
+ CanRetry = true,
+ Timestamp = DateTime.UtcNow
+ };
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] TIMEOUT: operation exceeded {timeoutSeconds}s");
+ result.EndTime = DateTime.UtcNow;
+ GeneralTracer.Error($"Driver update timed out: {driverInfo.Name}");
+ return result;
+ }
+
+ if (!lastStepResult.Success)
+ {
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] FAILED at step '{step.StepName}': {lastStepResult.ErrorMessage}");
+ break;
+ }
+
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Step '{step.StepName}' completed");
+ OnStepCompleted?.Invoke(step.StepName);
+ }
+
+ // Check if all steps passed
+ if (lastStepResult?.Success == true)
+ {
+ result.Success = true;
+ result.Status = UpdateStatus.Succeeded;
+ result.Message = "Driver update completed successfully";
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Update completed successfully");
+ GeneralTracer.Info($"Driver update completed successfully: {driverInfo.Name}");
+ }
+ else
+ {
+ result.Success = false;
+ result.Status = UpdateStatus.Failed;
+
+ if (lastStepResult?.ErrorMessage is not null)
+ {
+ result.Error = new ErrorInfo
+ {
+ Type = ErrorType.InstallationFailed,
+ Code = "ERR_PIPELINE",
+ Message = lastStepResult.ErrorMessage,
+ Timestamp = DateTime.UtcNow
+ };
+ }
+
+ // Attempt rollback if backup exists
+ var backupPath = result.BackupPath;
+ context.Bag.TryGetValue("BackupPath", out var bagPath);
+ backupPath ??= bagPath?.ToString();
+
+ if (!string.IsNullOrEmpty(backupPath))
+ {
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Attempting rollback");
+ var rolledBack = await TryRollbackAsync(backupPath, linkedCts.Token);
+ if (rolledBack)
+ {
+ result.RolledBack = true;
+ result.Status = UpdateStatus.RolledBack;
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Rollback completed");
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ GeneralTracer.Error($"Unexpected error during driver update: {ex}", ex);
+ result.Success = false;
+ result.Status = UpdateStatus.Failed;
+ result.Error = MapExceptionToErrorInfo(ex);
+ result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] ERROR: {ex.Message}");
+ }
+ finally
+ {
+ result.EndTime = DateTime.UtcNow;
+ GeneralTracer.Info($"Driver update finished. Duration={result.DurationMs}ms, Success={result.Success}");
+ ReportProgress(100, result.Success ? "Completed" : "Failed");
+ OnUpdateCompleted?.Invoke(result);
+ }
+
+ return result;
+ }
+
+ ///
+ public async Task ValidateAsync(
+ DriverInfo driverInfo,
+ CancellationToken cancellationToken = default)
+ {
+ try
+ {
+ if (!File.Exists(driverInfo.FilePath))
+ {
+ GeneralTracer.Error($"Driver file not found: {driverInfo.FilePath}");
+ return false;
+ }
+
+ if (!string.IsNullOrEmpty(driverInfo.Hash))
+ {
+ if (!await _validator.ValidateIntegrityAsync(
+ driverInfo.FilePath, driverInfo.Hash, driverInfo.HashAlgorithm, cancellationToken))
+ {
+ return false;
+ }
+ }
+
+ if (driverInfo.TrustedPublishers.Count > 0)
+ {
+ if (!await _validator.ValidateSignatureAsync(
+ driverInfo.FilePath, driverInfo.TrustedPublishers, cancellationToken))
+ {
+ return false;
+ }
+ }
+
+ return await _validator.ValidateCompatibilityAsync(driverInfo, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ GeneralTracer.Error("Driver validation failed", ex);
+ return false;
+ }
+ }
+
+ ///
+ public Task BackupAsync(
+ DriverInfo driverInfo,
+ string backupPath,
+ CancellationToken cancellationToken = default)
+ {
+ return _backup.BackupAsync(driverInfo.FilePath, backupPath, cancellationToken);
+ }
+
+ ///
+ public virtual async Task RollbackAsync(
+ string backupPath,
+ CancellationToken cancellationToken = default)
+ {
+ return await TryRollbackAsync(backupPath, cancellationToken);
+ }
+
+ ///
+ public virtual async Task> GetDriversFromDirectoryAsync(
+ string directoryPath,
+ string? searchPattern = null,
+ CancellationToken cancellationToken = default)
+ {
+ return await Task.Run(() =>
+ {
+ var drivers = new List();
+
+ if (!Directory.Exists(directoryPath))
+ {
+ GeneralTracer.Warn($"Directory not found: {directoryPath}");
+ return drivers;
+ }
+
+ var pattern = searchPattern ?? GetDefaultSearchPattern();
+ var files = Directory.GetFiles(directoryPath, pattern, SearchOption.AllDirectories);
+
+ foreach (var file in files)
+ {
+ try
+ {
+ var driverInfo = ParseDriverFromFile(file);
+ if (driverInfo is not null)
+ drivers.Add(driverInfo);
+ }
+ catch (Exception ex)
+ {
+ GeneralTracer.Debug($"Skipping file {file}: {ex.Message}");
+ }
+ }
+
+ return drivers;
+ }, cancellationToken);
+ }
+
+ // ─── Abstract / Virtual Members ────────────────────────────────────
+
+ ///
+ /// Platform-specific driver installation logic. Subclasses must implement this.
+ ///
+ /// Driver information.
+ /// Update strategy.
+ /// Cancellation token.
+ /// Thrown when installation fails.
+ protected abstract Task InstallCoreAsync(
+ DriverInfo driverInfo,
+ UpdateStrategy strategy,
+ CancellationToken cancellationToken);
+
+ ///
+ /// Returns the ordered pipeline steps for the given strategy.
+ /// Subclasses can override to insert platform-specific steps (e.g., permission check).
+ ///
+ /// Update strategy.
+ /// Ordered pipeline steps.
+ protected virtual IEnumerable GetPipelineSteps(UpdateStrategy strategy)
+ {
+ yield return DefaultPipelineSteps.CreateValidateStep(_validator);
+ yield return DefaultPipelineSteps.CreateBackupStep(_backup);
+ yield return DefaultPipelineSteps.CreateInstallStep(InstallCoreAsync);
+ yield return DefaultPipelineSteps.CreateVerifyStep(VerifyInstallationAsync);
+ }
+
+ ///
+ /// Post-install verification. Default implementation always returns true.
+ /// Subclasses can override to provide platform-specific verification.
+ ///
+ protected virtual Task VerifyInstallationAsync(
+ DriverInfo driverInfo,
+ CancellationToken cancellationToken)
+ {
+ return Task.FromResult(true);
+ }
+
+ ///
+ /// Returns the default file search pattern for the current platform.
+ ///
+ protected virtual string GetDefaultSearchPattern() => "*.*";
+
+ ///
+ /// Parses driver information from a file. Subclasses should override for platform-specific formats.
+ ///
+ protected virtual DriverInfo? ParseDriverFromFile(string filePath)
+ {
+ return new DriverInfo
+ {
+ Name = Path.GetFileNameWithoutExtension(filePath),
+ FilePath = filePath,
+ Version = "1.0.0"
+ };
+ }
+
+ // ─── Events ────────────────────────────────────────────────────────
+
+ ///
+ /// Raised when a pipeline step starts executing.
+ ///
+ public event Action? OnStepStarted;
+
+ ///
+ /// Raised when a pipeline step completes successfully.
+ ///
+ public event Action? OnStepCompleted;
+
+ ///
+ /// Raised when the entire update process completes.
+ ///
+ public event Action? OnUpdateCompleted;
+
+ ///
+ /// Raised to report progress (percentage, message).
+ ///
+ public event Action? OnProgress;
+
+ // ─── Helpers ───────────────────────────────────────────────────────
+
+ ///
+ /// Reports progress through the OnProgress event.
+ ///
+ protected void ReportProgress(int percentage, string message)
+ {
+ OnProgress?.Invoke(percentage, message);
+ }
+
+ ///
+ /// Attempts to roll back the driver to the given backup path.
+ ///
+ protected virtual async Task TryRollbackAsync(
+ string backupPath,
+ CancellationToken cancellationToken)
+ {
+ try
+ {
+ GeneralTracer.Info($"Rolling back from: {backupPath}");
+
+ if (!Directory.Exists(backupPath))
+ {
+ GeneralTracer.Error($"Backup directory not found: {backupPath}");
+ return false;
+ }
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ GeneralTracer.Error("Rollback failed", ex);
+ return false;
+ }
+ }
+
+ ///
+ /// Maps an exception to a structured object.
+ ///
+ protected virtual ErrorInfo MapExceptionToErrorInfo(Exception ex)
+ {
+ return new ErrorInfo
+ {
+ Code = ex switch
+ {
+ DriverPermissionException => "ERR_PERM",
+ DriverValidationException => "ERR_VALID",
+ DriverInstallationException dex => dex.CanRetry ? "ERR_INSTALL_RETRY" : "ERR_INSTALL",
+ DriverBackupException => "ERR_BACKUP",
+ DriverRollbackException => "ERR_ROLLBACK",
+ OperationCanceledException => "ERR_TIMEOUT",
+ _ => "ERR_UNKNOWN"
+ },
+ Type = ex switch
+ {
+ DriverPermissionException => ErrorType.PermissionDenied,
+ DriverValidationException => ErrorType.HashValidationFailed,
+ DriverBackupException => ErrorType.BackupFailed,
+ DriverRollbackException => ErrorType.RollbackFailed,
+ OperationCanceledException => ErrorType.Timeout,
+ _ => ErrorType.Unknown
+ },
+ Message = ex.Message,
+ Details = ex.ToString(),
+ StackTrace = ex.StackTrace,
+ Timestamp = DateTime.UtcNow,
+ CanRetry = ex is DriverInstallationException die && die.CanRetry,
+ SuggestedResolution = GetSuggestedResolution(ex)
+ };
+ }
+
+ private static string GetSuggestedResolution(Exception ex)
+ {
+ return ex switch
+ {
+ DriverPermissionException => "Restart the application with administrator/root privileges.",
+ DriverValidationException dv => $"Check the driver file integrity and retry. Details: {dv.Message}",
+ DriverInstallationException => "Verify the driver is compatible with your system and try again.",
+ OperationCanceledException => "Increase the timeout value in UpdateStrategy.TimeoutSeconds.",
+ _ => "Check logs for details and retry."
+ };
+ }
+}
diff --git a/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/DefaultPipelineSteps.cs b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/DefaultPipelineSteps.cs
new file mode 100644
index 00000000..3b04d02f
--- /dev/null
+++ b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/DefaultPipelineSteps.cs
@@ -0,0 +1,159 @@
+using GeneralUpdate.Common.Shared;
+using GeneralUpdate.Drivelution.Abstractions;
+using GeneralUpdate.Drivelution.Abstractions.Models;
+using GeneralUpdate.Drivelution.Core.Utilities;
+
+namespace GeneralUpdate.Drivelution.Core.Pipeline;
+
+///
+/// Built-in pipeline step implementations for the standard driver update flow.
+///
+internal static class DefaultPipelineSteps
+{
+ ///
+ /// Creates the validate step: checks file existence, hash integrity, signature, and compatibility.
+ ///
+ public static IPipelineStep CreateValidateStep(IDriverValidator validator)
+ {
+ return new DelegateStep("Validate", async (context, ct) =>
+ {
+ var driver = context.DriverInfo;
+ var strategy = context.Strategy;
+
+ context.Result.Status = UpdateStatus.Validating;
+ context.Result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Validating driver");
+
+ // File existence check
+ if (!File.Exists(driver.FilePath))
+ {
+ GeneralTracer.Error($"Driver file not found: {driver.FilePath}");
+ return PipelineResult.Fail($"Driver file not found: {driver.FilePath}");
+ }
+
+ // Hash validation (skip if configured)
+ if (!strategy.SkipHashValidation && !string.IsNullOrEmpty(driver.Hash))
+ {
+ if (!await validator.ValidateIntegrityAsync(
+ driver.FilePath, driver.Hash, driver.HashAlgorithm, ct))
+ {
+ return PipelineResult.Fail("Driver hash validation failed");
+ }
+ }
+
+ // Signature validation (skip if configured)
+ if (!strategy.SkipSignatureValidation && driver.TrustedPublishers.Count > 0)
+ {
+ if (!await validator.ValidateSignatureAsync(
+ driver.FilePath, driver.TrustedPublishers, ct))
+ {
+ return PipelineResult.Fail("Driver signature validation failed");
+ }
+ }
+
+ // Compatibility check
+ if (!await validator.ValidateCompatibilityAsync(driver, ct))
+ {
+ return PipelineResult.Fail(
+ $"Driver is not compatible with the current platform. " +
+ $"Target: {driver.TargetOS} {driver.Architecture}, " +
+ $"Current: {CompatibilityChecker.GetCurrentOS()} {CompatibilityChecker.GetCurrentArchitecture()}");
+ }
+
+ return PipelineResult.Ok();
+ });
+ }
+
+ ///
+ /// Creates the backup step: backs up the current driver before installation.
+ ///
+ public static IPipelineStep CreateBackupStep(IDriverBackup backup)
+ {
+ return new DelegateStep("Backup", async (context, ct) =>
+ {
+ context.Result.Status = UpdateStatus.BackingUp;
+ context.Result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Creating backup");
+
+ var backupPath = Path.Combine(
+ context.Strategy.BackupPath,
+ $"backup_{context.DriverInfo.Name}_{DateTime.Now:yyyyMMddHHmmss}");
+
+ if (await backup.BackupAsync(context.DriverInfo.FilePath, backupPath, ct))
+ {
+ context.Result.BackupPath = backupPath;
+ context.Bag["BackupPath"] = backupPath;
+ GeneralTracer.Info($"Backup created at: {backupPath}");
+ return PipelineResult.Ok();
+ }
+
+ return PipelineResult.Fail("Failed to create driver backup");
+ },
+ shouldExecute: context => context.Strategy.RequireBackup);
+ }
+
+ ///
+ /// Creates the install step: delegates to the platform-specific InstallCoreAsync method.
+ ///
+ public static IPipelineStep CreateInstallStep(
+ Func installCore)
+ {
+ return new DelegateStep("Install", async (context, ct) =>
+ {
+ context.Result.Status = UpdateStatus.Updating;
+ context.Result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Installing driver");
+
+ await installCore(context.DriverInfo, context.Strategy, ct);
+
+ return PipelineResult.Ok();
+ });
+ }
+
+ ///
+ /// Creates the verify step: confirms the driver was installed correctly.
+ ///
+ public static IPipelineStep CreateVerifyStep(
+ Func> verifyCore)
+ {
+ return new DelegateStep("Verify", async (context, ct) =>
+ {
+ context.Result.Status = UpdateStatus.Verifying;
+ context.Result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] Verifying installation");
+
+ var verified = await verifyCore(context.DriverInfo, ct);
+
+ if (!verified)
+ {
+ // Non-fatal: log warning but don't fail the whole update
+ GeneralTracer.Warn("Driver installation verification returned false");
+ context.Result.StepLogs.Add($"[{DateTime.Now:HH:mm:ss}] WARNING: Verification inconclusive");
+ }
+
+ return PipelineResult.Ok();
+ });
+ }
+
+ ///
+ /// Lightweight step implementation using delegates.
+ ///
+ private sealed class DelegateStep : IPipelineStep
+ {
+ private readonly Func> _execute;
+ private readonly Func _shouldExecute;
+
+ public string StepName { get; }
+
+ public DelegateStep(
+ string stepName,
+ Func> execute,
+ Func? shouldExecute = null)
+ {
+ StepName = stepName;
+ _execute = execute;
+ _shouldExecute = shouldExecute ?? (_ => true);
+ }
+
+ public bool ShouldExecute(PipelineContext context) => _shouldExecute(context);
+
+ public Task ExecuteAsync(PipelineContext context, CancellationToken cancellationToken)
+ => _execute(context, cancellationToken);
+ }
+}
diff --git a/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/RetryPolicy.cs b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/RetryPolicy.cs
new file mode 100644
index 00000000..52f2e146
--- /dev/null
+++ b/src/c#/GeneralUpdate.Drivelution/Core/Pipeline/RetryPolicy.cs
@@ -0,0 +1,134 @@
+namespace GeneralUpdate.Drivelution.Core.Pipeline;
+
+///
+/// Configurable retry policy for pipeline step execution.
+///
+public class RetryPolicy
+{
+ ///
+ /// Maximum number of retry attempts.
+ ///
+ public int MaxRetries { get; }
+
+ ///
+ /// Delay between retries.
+ ///
+ public TimeSpan Delay { get; }
+
+ ///
+ /// Whether to use exponential backoff (doubles delay each retry).
+ ///
+ public bool UseExponentialBackoff { get; }
+
+ ///
+ /// Creates a retry policy from defaults (3 retries, 5s interval, no backoff).
+ ///
+ public static RetryPolicy Default { get; } = new(3, TimeSpan.FromSeconds(5));
+
+ ///
+ /// Creates a retry policy with no retries.
+ ///
+ public static RetryPolicy NoRetry { get; } = new(0, TimeSpan.Zero);
+
+ ///
+ /// Initializes a new retry policy.
+ ///
+ /// Maximum retry attempts.
+ /// Delay between retries.
+ /// Whether to double delay each retry.
+ public RetryPolicy(int maxRetries, TimeSpan delay, bool useExponentialBackoff = false)
+ {
+ MaxRetries = maxRetries;
+ Delay = delay;
+ UseExponentialBackoff = useExponentialBackoff;
+ }
+
+ ///
+ /// Creates a RetryPolicy from .
+ ///
+ public static RetryPolicy FromOptions(Abstractions.Configuration.DrivelutionOptions? options)
+ {
+ if (options is null)
+ return Default;
+
+ return new RetryPolicy(
+ options.DefaultRetryCount > 0 ? options.DefaultRetryCount : 3,
+ TimeSpan.FromSeconds(options.DefaultRetryIntervalSeconds > 0 ? options.DefaultRetryIntervalSeconds : 5),
+ useExponentialBackoff: options.UseExponentialBackoff);
+ }
+
+ ///
+ /// Executes an asynchronous operation with retry logic.
+ ///
+ /// The operation to execute.
+ /// Cancellation token.
+ /// The operation result.
+ public async Task ExecuteAsync(
+ Func> operation,
+ CancellationToken cancellationToken = default)
+ {
+ int attempt = 0;
+ while (true)
+ {
+ try
+ {
+ return await operation(cancellationToken);
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch when (attempt < MaxRetries)
+ {
+ attempt++;
+ var delay = UseExponentialBackoff
+ ? TimeSpan.FromMilliseconds(Delay.TotalMilliseconds * Math.Pow(2, attempt - 1))
+ : Delay;
+
+ if (delay > TimeSpan.Zero)
+ await Task.Delay(delay, cancellationToken);
+ }
+ }
+ }
+
+ ///
+ /// Executes an asynchronous operation with retry logic, returning a boolean success.
+ ///
+ /// The operation to execute (returns true on success).
+ /// Cancellation token.
+ /// True if the operation succeeded within retry limits.
+ public async Task ExecuteWithRetryAsync(
+ Func> operation,
+ CancellationToken cancellationToken = default)
+ {
+ int attempt = 0;
+ while (true)
+ {
+ try
+ {
+ if (await operation(cancellationToken))
+ return true;
+
+ if (attempt >= MaxRetries)
+ return false;
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch
+ {
+ if (attempt >= MaxRetries)
+ return false;
+ }
+
+ attempt++;
+ var delay = UseExponentialBackoff
+ ? TimeSpan.FromMilliseconds(Delay.TotalMilliseconds * Math.Pow(2, attempt - 1))
+ : Delay;
+
+ if (delay > TimeSpan.Zero)
+ await Task.Delay(delay, cancellationToken);
+ }
+ }
+}