From f0831742d623886584a4901e87b2f4d8bbea2a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Tue, 27 Jan 2026 02:51:16 +0100 Subject: [PATCH] CmdPal: Remove deadlock bait from AppListItem (#45076) ## Summary of the Pull Request This PR removes a Task.Wait() call from lazy-loading AppListItem details that could be invoked on the UI thread and lead to a deadlock. It now follows the same pattern previously used for loading icons in the same class, which has proven to work well. Prevents #44938 from stepping on this landmine. Cherry-picked from #44973. ## PR Checklist - [x] Closes: #45074 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **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 ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../Microsoft.CmdPal.Ext.Apps/AppListItem.cs | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs index 176fae30d2..d907277ddc 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs @@ -17,12 +17,25 @@ public sealed partial class AppListItem : ListItem { private readonly AppCommand _appCommand; private readonly AppItem _app; - private readonly Lazy
_details; private readonly Lazy> _iconLoadTask; + private readonly Lazy> _detailsLoadTask; private InterlockedBoolean _isLoadingIcon; + private InterlockedBoolean _isLoadingDetails; - public override IDetails? Details { get => _details.Value; set => base.Details = value; } + public override IDetails? Details + { + get + { + if (_isLoadingDetails.Set()) + { + _ = LoadDetailsAsync(); + } + + return base.Details; + } + set => base.Details = value; + } public override IIconInfo? Icon { @@ -52,16 +65,22 @@ public sealed partial class AppListItem : ListItem MoreCommands = AddPinCommands(_app.Commands!, isPinned); - _details = new Lazy
(() => - { - var t = BuildDetails(); - t.Wait(); - return t.Result; - }); - + _detailsLoadTask = new Lazy>(BuildDetails); _iconLoadTask = new Lazy>(async () => await FetchIcon(useThumbnails)); } + private async Task LoadDetailsAsync() + { + try + { + Details = await _detailsLoadTask.Value; + } + catch (Exception ex) + { + Logger.LogWarning($"Failed to load details for {AppIdentifier}\n{ex}"); + } + } + private async Task LoadIconAsync() { try