Windows 应用 SDK桌面应用的应用生命周期

本文介绍从启动到终止Windows 应用 SDK桌面应用的生命周期。 了解生命周期有助于管理状态、节省资源并提供流畅的用户体验。

Important

与 UWP 应用不同,桌面应用(包括 WinUI 3)在转入后台时无需遵循 UWP 进程生命周期管理 (PLM) 模型中的自动挂起和终止机制。 他们继续运行,直到用户关闭或进程退出。 但是,打包的桌面应用仍受系统范围的电源和资源策略的约束,例如,当设备睡眠时,新式待机可能会暂停所有用户模式进程(包括应用),Windows可能会应用效率模式(EcoQoS)来限制后台或最小化应用的 CPU 优先级和服务质量。 你的应用仍应妥善处理意外关闭情况(例如断电、操作系统更新,或用户通过任务管理器结束进程),并且不应假定它在后台运行时始终能够以满速使用 CPU 资源。

生命周期概述

Windows 应用 SDK桌面应用具有比 UWP 更简单的生命周期:

State Description
未运行 应用进程尚未启动。
正在运行 应用处于活动状态。 它可能或可能没有可见的窗口。
关闭 用户(或系统)结束了该过程。

由于没有挂起状态,因此无需像 UWP 应用那样处理 SuspendingResuming 事件。 相反,请专注于:

  • 当窗口关闭或应用关闭时保存用户状态。
  • 处理激活(启动、文件、协议或其他激活类型)。
  • 有效地管理后台工作,以节省便携式设备上的电池。

应用启动

当用户启动应用时,Microsoft。Ui。Xaml.Application.OnLaunched 方法运行。 使用它初始化主窗口并导航到第一页。

public partial class App : Microsoft.UI.Xaml.Application
{
    private Microsoft.UI.Xaml.Window? m_window;

    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        m_window = new MainWindow();
        m_window.Activate();
    }
}

// MainWindow is the window class generated by the WinUI 3 project
// template (MainWindow.xaml / MainWindow.xaml.cs).
public partial class MainWindow : Microsoft.UI.Xaml.Window
{
}

注释

Windows 应用 SDK桌面应用不会从系统接收PreviousExecutionState值。 如果需要在崩溃或意外终止后还原状态,请实施自己的状态暂留机制(例如,将状态保存到计时器上的本地文件或重要操作完成时)。

应用激活

Windows 应用 SDK 通过 Microsoft.Windows.AppLifecycle 命名空间提供丰富的激活支持。 应用可以通过以下方式激活:

  • 默认启动 - 用户选择应用图标。
  • 文件激活 - 用户打开与应用关联的文件类型。
  • 协议激活 - 调用注册到应用的 URI 方案。
  • 启动激活 - 你的应用注册以在用户登录时启动。
  • 其他 — Toast 通知、共享目标和其他激活类型。

使用 AppInstance.GetActivatedEventArgs 来确定激活类型:

using Microsoft.Windows.AppLifecycle;

var activatedArgs = AppInstance.GetCurrent().GetActivatedEventArgs();

switch (activatedArgs.Kind)
{
    case ExtendedActivationKind.File:
        var fileArgs = activatedArgs.Data as
            Windows.ApplicationModel.Activation.IFileActivatedEventArgs;
        // Handle the file
        break;

    case ExtendedActivationKind.Protocol:
        var protocolArgs = activatedArgs.Data as
            Windows.ApplicationModel.Activation.IProtocolActivatedEventArgs;
        // Handle the URI
        break;

    case ExtendedActivationKind.Launch:
    default:
        // Standard launch
        break;
}

打包应用通过 Package.appxmanifest 注册文件和协议激活。 未打包的应用没有清单文件,因此它们使用 Microsoft.Windows.AppLifecycle.ActivationRegistrationManager 在代码中注册相同的激活类型。 有关这两种方法的详细演练,请参阅适用于Windows 应用 SDK的应用激活

在后台和前台运行

桌面应用无论是否处于前台,都会继续运行。 当用户切换到另一个应用时,系统不会停止线程或回收内存。 但是,仍可以响应可见性更改以优化资源使用情况:

  • 在窗口最小化时释放高开销的 GPU 或渲染资源。
  • 当窗口失去焦点时暂停动画或媒体预览。
  • 降低后台轮询的定时器频率。

Microsoft.UI.Xaml.Window 不公开 VisibilityChanged 事件。 请改用 Window.Activated 事件来检测窗口何时获得或失去焦点,或使用 AppWindow.Changed 来检测呈现状态的变化(例如最小化或还原):

// m_window is the field declared on your App type (see "App launch" above).
Microsoft.UI.Xaml.Window m_window = this;

m_window.Activated += (sender, args) =>
{
    if (args.WindowActivationState == WindowActivationState.Deactivated)
    {
        // Window lost focus — consider reducing work,
        // for example pausing animations or media preview
    }
    else
    {
        // Window is active — resume normal work
    }
};

// To specifically detect minimize/restore, use AppWindow.Changed
var appWindow = m_window.AppWindow;
appWindow.Changed += (sender, args) =>
{
    if (args.DidPresenterChange)
    {
        if (sender.Presenter is OverlappedPresenter presenter &&
            presenter.State == OverlappedPresenterState.Minimized)
        {
            // Window is minimized — pause expensive rendering
        }
        else
        {
            // Window is restored — resume rendering
        }
    }
};

Tip

在电池供电的设备上,当应用不可见时减少后台工作会改善电池使用时间和系统响应能力,即使系统不强制暂停也是如此。

保存状态

由于桌面应用不会被挂起,因此你可以自行决定何时保存状态。 建议的方法:

  • 在窗口关闭时 - 处理 Window.Closed 事件以持久保存数据。
  • 定期保存 - 使用计时器以间隔保存状态(例如,每 60 秒)。
  • 在重要操作后——在用户完成重要操作后保存(例如完成一次编辑)。
// m_window is the field declared on your App type (see "App launch" above).
Microsoft.UI.Xaml.Window m_window = this;

m_window.Closed += (sender, args) =>
{
    SaveApplicationState();
};

// Replace with your own logic to persist app state.
void SaveApplicationState() { }

应用关闭和终止

桌面应用会在以下情况下终止:

  • 用户关闭最后一个窗口。
  • 你的代码调用 Application.Current.Exit()
  • 进程在外部结束(任务管理器,系统关闭)。

不存在像 UWP 中那样“被系统终止以释放资源”的状态。 您的应用会一直运行,直到其显式退出。

注释

如果应用崩溃,它会从头开始重启。 实现定期状态保存以最大程度地减少数据丢失。

与 UWP 应用生命周期的差异

Behavior UWP Windows 应用 SDK(桌面版)
自动暂停(PLM) 是——在后台停留几秒后 否 - 但整个设备仍可进入新式待机
系统终止以释放内存 是 — 挂起的应用可能会终止
Suspending / Resuming 事件 是的 不適用
预启动 是(选择加入)
后台状态已强制设定 是的 否 — 但效率模式 (EcoQoS) 可能会限制后台应用
终止后的状态恢复 良好用户体验所必需的 可选——自行实现