Martin777 Martin777 - 1 year ago 114
C# Question

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

In my UWP app I have a background task, triggered by a TimeTrigger. In the code of the background task I have this snippet ("first activity" and "second activity" in my example consume hardly any resources):

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

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

//... second activity, 90 seconds later


So my questions are:

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

  2. Where is the CPU quota documented per TriggerType?

Answer Source

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

As it is said in Background task resource constraints:

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

This constraint is also applied to TimeTrigger. But your code works, I suppose this is because you are debugging your background task with Visual Studio. When Visual Studio debugger is attached, Visual Studio will take control of the background tasks. The background tasks stay for helping the developer to debug. Without debugger, the background task that exceed CPU quotas should be cancelled by OS.

For example, if we use a background task like following:

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}");


And then test it by sideloading this app package. (For how to sideload UWP apps, please see Packaging UWP apps). Once the background task is triggered, we can find in Test.txt file (this file is usually under %USERPROFILE%\AppData\Local\Packages\{Package family name}\LocalState), the output is like following:

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

There are only "first activity" no "second activity". And in Event View, we can get information like following:
enter image description here These information are under Application and Services Logs → Microsoft → Windows → BackgroundTaskInfrastructure → Operational.

2.Where is the CPU quota documented per TriggerType?

There is no document about the CPU quota per trigger type. Ref 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.

Only a few triggers like ApplicationTrigger, MaintenanceTrigger and DeviceUseTrigger have a usage longer than 30 seconds. Background tasks should be lightweight to save battery life and provide a better user experience for foreground apps. It's a good practice to only run lightweight code in the background and make it finish within 30 seconds.