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

View File

@@ -178,7 +178,7 @@ public sealed partial class DockSettingsPage : Page
var tlcManager = App.Current.Services.GetService<TopLevelCommandManager>()!; var tlcManager = App.Current.Services.GetService<TopLevelCommandManager>()!;
foreach (var item in tlcManager.DockBands) foreach (var item in tlcManager.GetDockBandsSnapshot())
{ {
if (item.IsDockBand) if (item.IsDockBand)
{ {
@@ -197,7 +197,7 @@ public sealed partial class DockSettingsPage : Page
var tlcManager = App.Current.Services.GetService<TopLevelCommandManager>()!; var tlcManager = App.Current.Services.GetService<TopLevelCommandManager>()!;
var settingsModel = App.Current.Services.GetService<SettingsModel>()!; var settingsModel = App.Current.Services.GetService<SettingsModel>()!;
var dockViewModel = App.Current.Services.GetService<DockViewModel>()!; var dockViewModel = App.Current.Services.GetService<DockViewModel>()!;
var allBands = tlcManager.DockBands; var allBands = tlcManager.GetDockBandsSnapshot();
foreach (var band in allBands) foreach (var band in allBands)
{ {
var setting = band.DockBandSettings; var setting = band.DockBandSettings;