using SharepointToolbox.Core.Models; namespace SharepointToolbox.Services; public static class BulkOperationRunner { /// /// Runs a bulk operation with continue-on-error semantics, per-item result tracking, /// and cancellation support. OperationCanceledException propagates immediately. /// public static async Task> RunAsync( IReadOnlyList items, Func processItem, IProgress progress, CancellationToken ct) { var results = new List>(); for (int i = 0; i < items.Count; i++) { ct.ThrowIfCancellationRequested(); progress.Report(new OperationProgress(i + 1, items.Count, $"Processing {i + 1}/{items.Count}...")); try { await processItem(items[i], i, ct); results.Add(BulkItemResult.Success(items[i])); } catch (OperationCanceledException) { throw; } catch (Exception ex) { results.Add(BulkItemResult.Failed(items[i], ex.Message)); } } progress.Report(new OperationProgress(items.Count, items.Count, "Complete.")); return new BulkOperationSummary(results); } }