mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +01:00
Adding Lock to RecentCommandsManager (#40507)
According to Issue #40447 Without the Lock in RecentCommandsManager we get Exception: Collection was modified; enumeration operation may not execute. It indicated that while GetCommandHistoryWeight was enumerating History, another method (likely AddHistoryItem) modified it at the same time. Since List is not thread-safe, simultaneous read+write can break it. ## Summary of the Pull Request <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] **Closes:** #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Unit Tests all pass, Manually Tested as Well - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx I've checked that in this project we use the new .NET 9 locking instead of object locking and implemented it according to rest of the locks ## Detailed Description of the Pull Request / Additional comments I've Manually tested it and also made sure that all the unit test pass ## Validation Steps Performed
This commit is contained in:
@@ -12,11 +12,15 @@ public partial class RecentCommandsManager : ObservableObject
|
|||||||
[JsonInclude]
|
[JsonInclude]
|
||||||
internal List<HistoryItem> History { get; set; } = [];
|
internal List<HistoryItem> History { get; set; } = [];
|
||||||
|
|
||||||
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
public RecentCommandsManager()
|
public RecentCommandsManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetCommandHistoryWeight(string commandId)
|
public int GetCommandHistoryWeight(string commandId)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
var entry = History
|
var entry = History
|
||||||
.Index()
|
.Index()
|
||||||
@@ -48,8 +52,11 @@ public partial class RecentCommandsManager : ObservableObject
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void AddHistoryItem(string commandId)
|
public void AddHistoryItem(string commandId)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
{
|
{
|
||||||
var entry = History
|
var entry = History
|
||||||
.Where(item => item.CommandId == commandId)
|
.Where(item => item.CommandId == commandId)
|
||||||
@@ -71,4 +78,5 @@ public partial class RecentCommandsManager : ObservableObject
|
|||||||
History.RemoveRange(50, History.Count - 50);
|
History.RemoveRange(50, History.Count - 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user