优化后台活动

当应用不在前台时,后台任务允许应用运行代码。 在桌面Windows 应用 SDK应用程序中,后台活动比 UWP 应用更具灵活性,但你仍应负责管理它,以确保为用户提供良好的体验。

Important

桌面Windows 应用 SDK应用不受与 UWP 应用相同的后台执行限制。 桌面应用可以自由运行后台线程、维护长时间运行的任务,并使用标准.NET线程模式。 但是,成为系统的良好公民意味着在用户未主动使用你的应用时尽量减少不必要的工作。

后台活动的最佳做法

遵循以下准则,使应用保持高效:

当用户不与应用交互时减少工作

当用户切换到其他应用或最小化窗口时,请降低计时器、网络轮询和其他后台工作的频率。 这会节省用户正在处理的应用的电池和释放系统资源。

使用高效的计划模式

使用基于定时器的调度,而不是频繁轮询循环。 对于周期性任务,请使用 DispatcherTimerSystem.Threading.Timer,并根据你的场景设置合适的间隔。

private DispatcherTimer _updateTimer;

private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
    if (args.WindowActivationState == WindowActivationState.Deactivated)
    {
        // Window is no longer active — slow down updates.
        _updateTimer.Interval = TimeSpan.FromSeconds(30);
    }
    else
    {
        // Window is active — use normal update rate.
        _updateTimer.Interval = TimeSpan.FromSeconds(2);
    }
}

响应电源和电池状态

检查系统的电源状态,并相应地调整应用的行为。 当设备使用电池供电时,减少后台活动,并考虑将非必要任务推迟到设备接入电源后再执行。

// Check power status using Windows.System.Power
var batteryStatus = Windows.System.Power.PowerManager.BatteryStatus;
var energySaverStatus = Windows.System.Power.PowerManager.EnergySaverStatus;

if (energySaverStatus == Windows.System.Power.EnergySaverStatus.On)
{
    // Reduce background work when Battery Saver is active.
    DisableNonEssentialUpdates();
}

void DisableNonEssentialUpdates()
{
    // Pause non-essential timers, syncs, and animations here.
}

在应用关闭时取消后台工作

当应用关闭时,使用 CancellationToken 模式取消任何剩余的后台任务。 这可以防止应用在不再可见后保存系统资源。

private CancellationTokenSource _cts = new();

private async Task DoBackgroundWorkAsync()
{
    while (!_cts.Token.IsCancellationRequested)
    {
        await Task.Delay(TimeSpan.FromSeconds(10), _cts.Token);
        // Perform periodic work.
    }
}

private void MainWindow_Closed(object sender, WindowEventArgs args)
{
    _cts.Cancel();
}

将后台任务与包标识配合使用

如果应用打包了 MSIX,则还可以注册后台任务,以响应系统触发器(例如网络状态更改、时区或用户状态)。 这些任务使用 UWP 中可用的相同 BackgroundTaskBuilder API。 有关更多信息,请参阅 使用后台任务支持你的应用

注释

打包应用(MSIX)可以使用 BackgroundTaskBuilder 来处理由系统触发的工作。 未打包的桌面应用应改用标准.NET线程模式。