UWP:为什么我的后台任务(使用 TimeTrigger)可以超过 CPU 配额?

UWP: Why can I exceed the CPU quota with my background task (using TimeTrigger)?

在我的 UWP 应用程序中,我有一个由 TimeTrigger 触发的后台任务。在后台任务的代码中,我有这个片段("first activity" 和 "second activity" 在我的例子中几乎不消耗任何资源):

var deferral = args.TaskInstance.GetDeferral();
await Task.Run(async () =>
{
    //... first activity

    await Task.Delay(TimeSpan.FromSeconds(90.0));

    //... second activity, 90 seconds later

});

所以我的问题是:

  1. 为什么上面的代码有效,正如文档中明确指出的那样"Background tasks are limited to 30 seconds of wall-clock usage"?

  2. 每个 TriggerType 记录的 CPU 配额在哪里?

1.Why does the above code work, as the documentation clearly says "Background tasks are limited to 30 seconds of wall-clock usage"?

正如Background task resource constraints中所说:

Background tasks are limited to 30 seconds of wall-clock usage.

此约束也适用于 TimeTrigger。但是您的代码有效,我想这是因为您正在使用 Visual Studio 调试后台任务。当附加 Visual Studio 调试器时,Visual Studio 将控制后台任务。后台任务用于帮助开发人员进行调试。没有调试器,超过 CPU 配额的后台任务应该被 OS 取消。

例如,如果我们使用如下后台任务:

public sealed class MyBackgroundTask : IBackgroundTask
{
    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        var deferral = taskInstance.GetDeferral();
        var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("Test.txt", CreationCollisionOption.OpenIfExists);
        await FileIO.AppendTextAsync(file, $"{DateTime.Now.ToString()} first activity{Environment.NewLine}");

        await Task.Delay(TimeSpan.FromSeconds(90.0));

        await FileIO.AppendTextAsync(file, $"{DateTime.Now.ToString()} second activity{Environment.NewLine}");

        deferral.Complete();
    }
}

然后通过旁加载此应用程序包对其进行测试。 (有关如何旁加载 UWP 应用程序,请参阅 Packaging UWP apps)。一旦触发了后台任务,我们可以在Test.txt文件中找到(这个文件一般在%USERPROFILE%\AppData\Local\Packages\{Package family name}\LocalState下),输出如下:

9/2/2016 3:06:35 PM first activity
9/2/2016 3:20:15 PM first activity

只有"first activity"个,没有"second activity"个。在事件视图中,我们可以获得如下信息:
这些信息位于 应用程序和服务日志 → Microsoft → Windows → BackgroundTaskInfrastructure → 操作.

2.Where is the CPU quota documented per TriggerType?

没有关于每个触发器类型的 CPU 配额的文档。参考 Background task guidance:

CPU quotas: Background tasks are limited by the amount of wall-clock usage time they get based on trigger type. Most triggers are limited to 30 seconds of wall-clock usage, while some have the ability to run up to 10 minutes in order to complete intensive tasks.

只有 ApplicationTriggerMaintenanceTriggerDeviceUseTrigger 等少数触发器的使用时间超过 30 秒。后台任务应该是轻量级的,以节省电池寿命并为前台应用程序提供更好的用户体验。只在后台 运行 轻量代码并使其在 30 秒内完成是一个很好的做法。