Viet Tran a38d04c3d5
feat(search): overhaul relevance and curated design data
Overhaul BM25 relevance, reasoning and data-quality contracts; refresh UI styles and framework guidance; add resilient text, chip, badge and micro-interaction guidance; strengthen release, provenance and catalog refresh gates; update bilingual documentation.
2026-08-14 00:08:23 +07:00

24 KiB

1NoCategoryGuidelineDescriptionDoDon'tCode GoodCode BadSeverityDocs URLApplies ToStatusVerified At
21XAMLUse x:Bind for compiled bindingsCompile-time validated bindings with better performancex:Bind for type-safe performant bindings{Binding} when x:Bind is available<TextBlock Text="{x:Bind ViewModel.Name, Mode=OneWay}"/><TextBlock Text="{Binding Name}"/>Highhttps://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extensionuwp legacydeprecated2026-08-13
32XAMLUse x:Load for deferred elementsDelay creation of elements until neededx:Load=False for hidden or conditional panelsLoading all UI elements at page load<StackPanel x:Name="AdvancedPanel" x:Load="{x:Bind ShowAdvanced, Mode=OneWay}">Collapsed StackPanel that is always instantiatedMediumhttps://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-load-attributeuwp legacydeprecated2026-08-13
43XAMLUse x:Phase for incremental item renderingRender list items in priority phasesx:Phase on secondary content in item DataTemplatesAll template content loaded in one pass<TextBlock x:Phase="1" Text="{x:Bind Description}"/>Complex DataTemplate with no phasingMediumhttps://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-phase-attributeuwp legacydeprecated2026-08-13
54XAMLUse x:DefaultBindModeReduce repetitive Mode= declarationsx:DefaultBindMode=OneWay on containersMode=OneWay on every individual x:Bind<StackPanel x:DefaultBindMode="OneWay">Mode=OneWay repeated on every binding in a panelLowhttps://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extensionuwp legacydeprecated2026-08-13
65XAMLUse x:DeferLoadStrategy for legacy supportDeferred loading before x:Load was availablex:Load (preferred) or x:DeferLoadStrategy=LazyEagerly loading rarely shown UIx:Load="False" (or x:DeferLoadStrategy="Lazy" on older targets)Always-loaded panels toggled with VisibilityLowhttps://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-deferloadstrategy-attributeuwp legacydeprecated2026-08-13
76ControlsUse NavigationView for app shellStandard UWP navigation pattern with hamburger menuNavigationView for top-level navigationCustom SplitView hamburger menu<NavigationView><NavigationView.MenuItems><NavigationViewItem Content="Home" Icon="Home"/></NavigationView.MenuItems></NavigationView>Custom SplitView with manual toggle buttonHighhttps://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/navigationviewuwp legacydeprecated2026-08-13
87ControlsUse CommandBar for app actionsStandard app bar for primary commandsCommandBar with AppBarButtonsCustom StackPanel toolbar<CommandBar><AppBarButton Icon="Save" Label="Save"/></CommandBar><StackPanel Orientation="Horizontal"><Button>Save</Button></StackPanel>Mediumhttps://learn.microsoft.com/en-us/windows/apps/develop/ui/controls/command-baruwp legacydeprecated2026-08-13
98ControlsUse ContentDialog for modalsSystem-styled modal dialogsContentDialog for confirmations and inputCustom popup overlays<ContentDialog Title="Confirm" PrimaryButtonText="Yes" CloseButtonText="No"/>Grid overlay with manual focus trappingMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/dialogs-and-flyouts/dialogsuwp legacydeprecated2026-08-13
109ControlsUse AutoSuggestBox for searchBuilt-in search box with suggestionsAutoSuggestBox with QuerySubmitted and SuggestionChosenTextBox with manual suggestion popup<AutoSuggestBox QueryIcon="Find" TextChanged="OnTextChanged" SuggestionChosen="OnChosen" QuerySubmitted="OnQuerySubmitted"/>TextBox with custom Popup and ListBox for suggestionsMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/auto-suggest-boxuwp legacydeprecated2026-08-13
1110ControlsUse CalendarDatePicker and TimePickerPlatform-consistent date and time selectionBuilt-in date and time pickersCustom date selection controls<CalendarDatePicker Header="Start date"/><TimePicker Header="Time"/>TextBox with date parsing and validationLowhttps://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/date-and-timeuwp legacydeprecated2026-08-13
1211ControlsUse PersonPicture for user avatarsConsistent avatar display with fallback initialsPersonPicture with DisplayName and ProfilePictureCustom Ellipse with ImageBrush for avatars<PersonPicture DisplayName="Jane Doe" ProfilePicture="{x:Bind AvatarUri}"/><Ellipse><Ellipse.Fill><ImageBrush ImageSource="avatar.png"/></Ellipse.Fill></Ellipse>Lowhttps://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/person-pictureuwp legacydeprecated2026-08-13
1312StylingUse ThemeResource for adaptive colorsColors that switch with light and dark themeThemeResource for all color referencesHardcoded hex values that break in dark modeForeground="{ThemeResource SystemControlForegroundBaseHighBrush}"Foreground="#000000"Highhttps://learn.microsoft.com/en-us/windows/uwp/design/style/coloruwp legacydeprecated2026-08-13
1413StylingUse Fluent Design materialsAcrylic translucent material for depthBuilt-in Fluent materials for depth and motionCustom shader effects for blur and reveal<Grid Background="{ThemeResource SystemControlAcrylicWindowBrush}"/>Custom CompositionEffectBrush recreating acrylicMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/style/acrylicuwp legacydeprecated2026-08-13
1514StylingUse Lightweight StylingOverride control resource keys for subtle changesLightweight styling resource overridesFull ControlTemplate copy for small tweaks<Button><Button.Resources><SolidColorBrush x:Key="ButtonBackground" Color="Blue"/></Button.Resources></Button>Entire ControlTemplate copied to change backgroundMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-styles#lightweight-stylinguwp legacydeprecated2026-08-13
1615StylingUse implicit styles for consistencyTargetType without x:Key applies to all instancesImplicit Style for default control appearanceRepeating Setters on every control instance<Style TargetType="Button"><Setter Property="CornerRadius" Value="4"/></Style>CornerRadius="4" on every Button in the pageMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/xaml-stylesuwp legacydeprecated2026-08-13
1716StylingUse VisualStateManager for visual statesDefine visual states with Setters that change properties when triggeredVisualStateGroup containing VisualStates with Setter targetsToggling Visibility from code-behind on SizeChanged<VisualStateGroup><VisualState x:Name="Wide"><VisualState.Setters><Setter Target="root.Orientation" Value="Horizontal"/></VisualState.Setters></VisualState></VisualStateGroup>SizeChanged handler that flips Orientation in code-behindHighhttps://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xamluwp legacydeprecated2026-08-13
1817NavigationUse Frame for page navigationWindows.UI.Xaml.Controls.Frame for UWP page navigationFrame.Navigate with typed parametersSwapping UserControls manuallyrootFrame.Navigate(typeof(DetailPage), itemId);contentArea.Content = new DetailPage();Mediumhttps://learn.microsoft.com/en-us/windows/uwp/design/basics/navigate-between-two-pagesuwp legacydeprecated2026-08-13
1918NavigationHandle back button correctlyProvide an in-app Back button styled with NavigationBackButtonNormalStyle and handle SystemNavigationManager.BackRequested for hardware back gamepad B and Tablet-Mode back; also handle CoreDispatcher.AcceleratorKeyActivated for Alt+LeftIn-app NavigationBackButtonNormalStyle button plus SystemNavigationManager.BackRequested handlerRelying on the deprecated title-bar back button (AppViewBackButtonVisibility) or ignoring system back signalsSystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;No back button support on phone or tabletHighhttps://learn.microsoft.com/en-us/windows/uwp/ui-input/back-navigationuwp legacydeprecated2026-08-13
2019NavigationSupport deep linking with protocol activationRespond to URI activation and toast tapsOnActivated handler with proper page routingIgnoring activation argumentsprotected override void OnActivated(IActivatedEventArgs args) { if (args.Kind == ActivationKind.Protocol) { ... } }Empty OnActivated ignoring URI parametersMediumhttps://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-uri-activationuwp legacydeprecated2026-08-13
2120NavigationUse ConnectedAnimations for continuitySmooth transitions between pagesConnectedAnimationService for shared element transitionsAbrupt page transitions with no visual continuityConnectedAnimationService.GetForCurrentView().PrepareToAnimate("image", sourceImage);No transition animation between list and detailLowhttps://learn.microsoft.com/en-us/windows/uwp/design/motion/connected-animationuwp legacydeprecated2026-08-13
2221Data BindingImplement INotifyPropertyChangedEnable UI updates on property changesINotifyPropertyChanged on all ViewModelsAuto-properties without notificationpublic string Title { get => _title; set { _title = value; OnPropertyChanged(); } }public string Title { get; set; } expecting UI updatesHighhttps://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depthuwp legacydeprecated2026-08-13
2322Data BindingUse ObservableCollection for listsCollection change notifications for ItemsSourcesObservableCollection<T> for bound listsList<T> for data-bound collectionsObservableCollection<Item> Items { get; } = new();List<Item> Items { get; set; } = new();Highhttps://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depthuwp legacydeprecated2026-08-13
2423Data BindingUse function bindings with x:BindCall static methods directly in markupx:Bind to static converter methodsIValueConverter for trivial transforms<TextBlock Visibility="{x:Bind local:Converters.BoolToVisibility(IsActive), Mode=OneWay}"/>Full IValueConverter class for bool to VisibilityMediumhttps://learn.microsoft.com/en-us/windows/uwp/data-binding/function-bindingsuwp legacydeprecated2026-08-13
2524Data BindingSpecify Mode on x:Bindx:Bind defaults to OneTime not OneWayMode=OneWay or TwoWay when live updates neededOmitting Mode and getting stale UIText="{x:Bind Title, Mode=OneWay}"Text="{x:Bind Title}" expecting live updatesHighhttps://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extensionuwp legacydeprecated2026-08-13
2625Data BindingUse CollectionViewSource for groupingGroup and sort collections declarativelyCollectionViewSource for grouped ListView and GridViewManual grouping logic in code-behind<CollectionViewSource x:Key="GroupedItems" IsSourceGrouped="True" Source="{x:Bind GroupedData}"/>Manual loop building grouped StackPanelsMediumhttps://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depthuwp legacydeprecated2026-08-13
2726PerformanceUse ListView and GridView virtualizationOnly creates containers for visible itemsDefault virtualization in ListView and GridViewSetting ItemsPanel to non-virtualizing panel<ListView ItemsSource="{x:Bind Items}"/> (virtualizes by default)<ListView><ListView.ItemsPanel><ItemsPanelTemplate><StackPanel/></ItemsPanelTemplate></ListView.ItemsPanel></ListView>Highhttps://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listviewuwp legacydeprecated2026-08-13
2827PerformanceUse ISupportIncrementalLoadingLoad data on demand as user scrollsISupportIncrementalLoading for large datasetsLoading entire collection upfrontclass IncrementalSource : ObservableCollection<Item>, ISupportIncrementalLoadingawait LoadAll() loading 50K items at startupMediumhttps://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depthuwp legacydeprecated2026-08-13
2928PerformanceReduce XAML visual tree depthSimpler trees layout and render fasterFlat templates with minimal nestingDeeply nested panels in DataTemplates<StackPanel><TextBlock/><TextBlock/></StackPanel> in item template<Grid><Border><StackPanel><Grid>... 8 levels in item templateMediumhttps://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-xaml-loadinguwp legacydeprecated2026-08-13
3029PerformanceUse compiled bindings in DataTemplatesx:Bind in templates requires x:DataTypex:DataType on DataTemplate for compiled bindings{Binding} in item templates for large lists<DataTemplate x:DataType="local:Item"><TextBlock Text="{x:Bind Name}"/></DataTemplate><DataTemplate><TextBlock Text="{Binding Name}"/></DataTemplate>Highhttps://learn.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup-extensionuwp legacydeprecated2026-08-13
3130PerformanceProfile with Visual Studio diagnosticsMeasure before optimizingApplication Timeline and Memory Usage toolsGuessing at performance problemsVS Diagnostic Tools > Application TimelineOptimizing without profiling dataMediumhttps://learn.microsoft.com/en-us/visualstudio/profiling/application-timelineuwp legacydeprecated2026-08-13
3231ThreadingUse async/await for all IOKeep UI thread responsiveasync/await for file network and database operationsSynchronous IO blocking the UI threadvar file = await StorageFile.GetFileFromPathAsync(path);StorageFile.GetFileFromPathAsync(path).AsTask().Result;Highhttps://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-appsuwp legacydeprecated2026-08-13
3332ThreadingUse CoreDispatcher for UI thread accessPost work back to the UI thread from backgroundDispatcher.RunAsync from background threadsTouching UI elements from background threadsawait Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Status = "Done");textBlock.Text = "Done" from Task.RunHighhttps://learn.microsoft.com/en-us/uwp/api/windows.ui.core.coredispatcheruwp legacydeprecated2026-08-13
3433ThreadingOffload CPU work with Task.RunKeep compute-heavy work off UI threadTask.Run for CPU-bound operationsHeavy computation blocking UIvar result = await Task.Run(() => ProcessData(items));var result = ProcessData(items); freezing UIHighhttps://learn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-appsuwp legacydeprecated2026-08-13
3534ThreadingUse IProgress for status updatesReport progress from background operationsIProgress<T> for progress reporting to UIPolling shared variables for progressvar progress = new Progress<int>(p => ProgressBar.Value = p); await Task.Run(() => Process(progress));while (!done) { await Task.Delay(100); check shared field; }Mediumhttps://learn.microsoft.com/en-us/dotnet/api/system.progress-1uwp legacydeprecated2026-08-13
3635AdaptiveUse AdaptiveTrigger for responsive layoutsMinWindowWidth and MinWindowHeight triggers fire at standard breakpoints (640 small / 1008 medium)AdaptiveTrigger inside VisualState.StateTriggers with the 640 and 1008 breakpointsFixed layouts for a single screen size<VisualState.StateTriggers><AdaptiveTrigger MinWindowWidth="640"/></VisualState.StateTriggers>Single-column layout at all widthsHighhttps://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xamluwp legacydeprecated2026-08-13
3736AdaptiveDesign for multiple device familiesPhone tablet desktop Xbox and HoloLensDeviceFamily-specific views and resourcesDesktop-only design ignoring other form factorsDeviceFamily-Mobile/MainPage.xaml for phone-specific layoutFixed 1920x1080 layoutMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/layout/screen-sizes-and-breakpoints-for-responsive-designuwp legacydeprecated2026-08-13
3837AdaptiveUse RelativePanel for adaptive positioningControls position relative to each otherRelativePanel for layouts that reflow at breakpointsAbsolute positioning or fixed margins<Button RelativePanel.Below="title" RelativePanel.AlignLeftWithPanel="True"/><Button Margin="0,60,0,0"/> calculated from title heightMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml#relativepaneluwp legacydeprecated2026-08-13
3938AdaptiveSupport multi-window with secondary viewsOpen detached views with CoreApplication.CreateNewView and ApplicationViewSwitcherCreateNewView and TryShowAsStandaloneAsync for multi-document scenariosSingle-window assumptions when scenarios benefit from secondary viewsvar view = CoreApplication.CreateNewView(); await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { /* set content */ });Modal overlay used for content that should be a separate windowMediumhttps://learn.microsoft.com/en-us/windows/uwp/design/layout/show-multiple-viewsuwp legacydeprecated2026-08-13
4039AccessibilitySet AutomationPropertiesEnable Narrator and screen reader supportAutomationProperties.Name on all interactive controlsControls without accessible names<AppBarButton AutomationProperties.Name="Save document" Icon="Save"/><AppBarButton Icon="Save"/> without nameHighhttps://learn.microsoft.com/en-us/windows/uwp/design/accessibility/basic-accessibility-informationuwp legacydeprecated2026-08-13
4140AccessibilitySupport keyboard and gamepadAll functions reachable without touchTab navigation XYFocus and access keysTouch-only interactions<Button AccessKey="S" XYFocusDown="{x:Bind OtherButton}"/>No keyboard or gamepad supportHighhttps://learn.microsoft.com/en-us/windows/uwp/design/input/keyboard-interactionsuwp legacydeprecated2026-08-13
4241AccessibilitySupport contrast themesRespect system contrast themes (renamed from high contrast in Windows 11)ThemeResource brushes that adapt to contrast themesHardcoded colors that vanish under contrast themesForeground="{ThemeResource SystemControlForegroundBaseHighBrush}"Foreground="#444444"Highhttps://learn.microsoft.com/en-us/windows/uwp/design/accessibility/high-contrast-themesuwp legacydeprecated2026-08-13
4342AccessibilityTest with Narrator and Accessibility InsightsValidate screen reader and automation complianceRegular Narrator walkthrough and Accessibility Insights scanShipping without accessibility testingAccessibility Insights FastPass on every pageNo accessibility testing before releaseMediumhttps://accessibilityinsights.io/uwp legacydeprecated2026-08-13
4443ArchitectureUse MVVM patternSeparate View ViewModel and ModelViewModel with INotifyPropertyChanged and ICommandBusiness logic in code-behindViewModel bound via DataContext with commandsMainPage.xaml.cs with database calls and UI logicMediumhttps://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvmuwp legacydeprecated2026-08-13
4544ArchitectureUse Template Studio for scaffoldingProven project templates with navigation and servicesWindows Template Studio for new UWP projectsBlank project with manual boilerplateTemplate Studio with MVVM Toolkit and navigation serviceBlank App template building everything from scratchLowhttps://github.com/microsoft/TemplateStudiouwp legacydeprecated2026-08-13
4645ArchitectureUse dependency injectionRegister services for testabilityMicrosoft.Extensions.DI for service resolutionStatic singletons and manual constructionservices.AddTransient<MainViewModel>(); services.AddSingleton<IDataService, DataService>();DataService.Instance or new DataService() everywhereMediumhttps://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injectionuwp legacydeprecated2026-08-13
4746ArchitectureKeep platform APIs behind abstractionsIsolate WinRT APIs from business logicInterfaces wrapping StorageFile FilePicker etcDirect WinRT calls in ViewModelsIFileService wrapping FileOpenPicker and StorageFileFileOpenPicker usage directly in ViewModelMediumhttps://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvmuwp legacydeprecated2026-08-13
4847LifecycleHandle suspend and resumeUWP apps are suspended when not in foregroundSave state in OnSuspending and restore in OnLaunchedIgnoring app lifecycle losing user stateApplication.Current.Suspending += (s, e) => SaveState();No suspend handler losing in-progress form dataHighhttps://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycleuwp legacydeprecated2026-08-13
4948LifecycleUse ExtendedExecutionSession for background workRequest extended time for unfinished operationsExtendedExecutionSession for saving or uploadsAssuming background work completes after suspendvar session = new ExtendedExecutionSession { Reason = ExtendedExecutionReason.SavingData };Long upload with no extended execution that gets killed on suspendMediumhttps://learn.microsoft.com/en-us/windows/uwp/launch-resume/run-minimized-with-extended-executionuwp legacydeprecated2026-08-13
5049LifecycleHandle prelaunchApps must opt in to prelaunch via CoreApplication.EnablePrelaunch(true) starting in Windows 10 1607; check LaunchActivatedEventArgs.PrelaunchActivated to skip user-visible workOpt in with EnablePrelaunch and skip heavy init when PrelaunchActivated is truePerforming full initialization or navigating during prelaunchCoreApplication.EnablePrelaunch(true); if (e.PrelaunchActivated) return; // skip heavy initLoading all data and navigating on prelaunchMediumhttps://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-app-prelaunchuwp legacydeprecated2026-08-13
5150TestingUnit test ViewModelsTest logic without UI framework dependenciesxUnit or MSTest on ViewModel methodsTesting only through the running app[Fact] public async Task Load_PopulatesItems() { await vm.LoadAsync(); Assert.NotEmpty(vm.Items); }Manual testing by tapping through the appMediumhttps://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practicesuwp legacydeprecated2026-08-13
5251TestingUse WinAppDriver with Appium for UI testsAutomated UI testing for UWP (Coded UI Test was deprecated in Visual Studio 2019); WinAppDriver v1 is in low-maintenance mode and Appium 2 is the modern directionWinAppDriver with Appium for end-to-end testsManual regression testingsession.FindElementByAccessibilityId("SaveButton").Click();Manual click-through testing before each releaseMediumhttps://github.com/microsoft/WinAppDriveruwp legacydeprecated2026-08-13
5352TestingTest on multiple device familiesBehavior varies across phone desktop and XboxTest on device emulators and real hardwareDesktop-only testingTest on Mobile emulator and Xbox dev modeOnly running on local desktopMediumhttps://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portaluwp legacydeprecated2026-08-13
5453ArchitecturePrefer WinUI 3 for new projectsUWP is maintenance-only; WinUI 3 with the Windows App SDK is the recommended path for new Windows appsUse WinUI 3 with the Windows App SDK for every new Windows appStart a new Windows app on UWPNew project with Microsoft.WindowsAppSDK and WinUI 3New UWP project for a Windows appMediumhttps://learn.microsoft.com/en-us/windows/apps/get-started/uwp legacydeprecated2026-08-13
5554ArchitecturePlan migration to Windows App SDKMaintain existing UWP apps while planning migration to WinUI 3 and the Windows App SDK; do not expand UWP as the foundation for new Windows developmentUse the UWP migration guidance to plan an incremental migration or full port to WinUI 3Continue major new-app investment on UWP without a Windows App SDK migration planFollow the UWP to WinUI 3 migration guide for existing appsStart a new Windows app on UWP instead of WinUI 3Mediumhttps://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/overall-migration-strategyuwp legacydeprecated2026-08-13
5655LifecycleUse a deferral when saving async state on suspendSuspending grants only ~5 seconds before the OS may terminate; await work needs SuspendingOperation.GetDeferral and Complete or save returns before it finishesGetDeferral around async save calls and Complete in finallyAsync work that returns the suspending handler before completionasync void OnSuspending(object s, SuspendingEventArgs e) { var d = e.SuspendingOperation.GetDeferral(); try { await SaveAsync(); } finally { d.Complete(); } }async void OnSuspending(object s, SuspendingEventArgs e) { await SaveAsync(); } // handler returns before save completesMediumhttps://learn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycleuwp legacydeprecated2026-08-13