From e1b0eb96fd37973204b304f817b6313be56a0ac8 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Bajpai Date: Sat, 25 Jul 2026 21:23:48 +0530 Subject: [PATCH] fix: thread-safety in Parallel.ForEach cleanup and dry-run guard ordering --- src/Engine.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Engine.cs b/src/Engine.cs index 30a575c2..fd684c4f 100644 --- a/src/Engine.cs +++ b/src/Engine.cs @@ -152,15 +152,19 @@ public async Task RunAsync(Configuration config, bool dryRun, string? profileNam { _logger.LogInfo("\n--- Cleaning Up ---"); var removedItems = new ConcurrentBag(); + var cleanupLock = new object(); await Task.Run(() => Parallel.ForEach(itemsToRemove, uniqueId => { if (uniqueId.StartsWith("reg:")) { var parts = uniqueId.Substring(4).Split('|', 2); - if (parts.Length == 2 && _registry.Revert(parts[0], parts[1], dryRun) && !dryRun) + if (parts.Length == 2 && !dryRun && _registry.Revert(parts[0], parts[1], false)) { - removedItems.Add(uniqueId); - confirmedApplied.Remove(uniqueId); + lock (cleanupLock) + { + removedItems.Add(uniqueId); + confirmedApplied.Remove(uniqueId); + } } } else @@ -168,11 +172,14 @@ await Task.Run(() => Parallel.ForEach(itemsToRemove, uniqueId => var parts = uniqueId.Split(':', 2); if (parts.Length == 2 && _managers.TryGetValue(parts[0], out var mgr)) { - mgr.Uninstall(parts[1], dryRun); if (!dryRun) { - removedItems.Add(uniqueId); - confirmedApplied.Remove(uniqueId); + mgr.Uninstall(parts[1], false); + lock (cleanupLock) + { + removedItems.Add(uniqueId); + confirmedApplied.Remove(uniqueId); + } } } }