CmdPal: add locking TopLevelCommandManager.DockBands (#45898)

## Summary of the Pull Request

- Put enumeration of DockBands in
TopLevelCommandManager.ExtensionService_OnExtensionRemoved under correct
lock
- Return a snapshot of the dock bands list to prevent reading DockBands
without lock outside of TopLevelCommandManager

## PR Checklist

- [x] Closes: #45893
This commit is contained in:
Jiří Polášek
2026-03-09 12:48:58 +01:00
committed by GitHub
parent 0aca7c292c
commit f8453214fb
3 changed files with 16 additions and 5 deletions

View File

@@ -29,7 +29,7 @@ public sealed partial class DockViewModel
public ObservableCollection<DockBandViewModel> EndItems { get; } = new();
public ObservableCollection<TopLevelViewModel> AllItems => _topLevelCommandManager.DockBands;
public IReadOnlyList<TopLevelViewModel> AllItems => _topLevelCommandManager.GetDockBandsSnapshot();
public DockViewModel(
TopLevelCommandManager tlcManager,

View File

@@ -585,9 +585,9 @@ public sealed partial class TopLevelCommandManager : ObservableObject,
// Then find all the top-level commands that belonged to that extension
List<TopLevelViewModel> commandsToRemove = [];
List<TopLevelViewModel> bandsToRemove = [];
lock (TopLevelCommands)
foreach (var extension in extensions)
{
foreach (var extension in extensions)
lock (TopLevelCommands)
{
foreach (var command in TopLevelCommands)
{
@@ -597,7 +597,10 @@ public sealed partial class TopLevelCommandManager : ObservableObject,
commandsToRemove.Add(command);
}
}
}
lock (_dockBandsLock)
{
foreach (var band in DockBands)
{
var host = band.ExtensionHost;
@@ -675,6 +678,14 @@ public sealed partial class TopLevelCommandManager : ObservableObject,
return null;
}
public List<TopLevelViewModel> GetDockBandsSnapshot()
{
lock (_dockBandsLock)
{
return [.. DockBands];
}
}
public void Receive(ReloadCommandsMessage message) =>
_ = ReloadAllCommandsAsync();