This document discusses background tasks in Universal Windows Platform (UWP) apps. It describes how to implement background tasks using the IBackgroundTask interface, register background tasks to handle triggers like time changes or app updates, and handle constraints like CPU and network utilization limits. It also covers additional capabilities for lock screen apps like updating badges, tiles, and using time-based triggers.
2. Background Tasks
Allow apps to execute code when not active
App is suspended, but background tasks execute
No UI permitted except for tiles, toasts, and badges
Background tasks implement IBackgroundTask
Execute in response to triggers (e.g., SystemTrigger)
Tasks can optionally have conditions attached
BackgroundTaskBuilder class provides API for registering background
tasks
3. Background Task Constraints
CPU utilization is limited
Applies to both AC and DC power
Lock-screen apps get 2 seconds every 15 minutes
Others receive 1 second every 2 hours
Network utilization is limited
Limited on DC power; no limit for AC
Bandwidth varies depending on network hardware
For example, WiFi gets more bandwidth than mobile
If quota is reached, task is temporarily suspended
4. Implementing a Background Task
Add "Windows Runtime Component" project to solution and reference it
from main project
Add class that implements IBackgroundTask
Must be public and sealed
Override Run; use deferral if performing async calls
Register background task from main app
First make sure it isn't already registered
Specify trigger and (optionally) conditions
Add background-task declaration to manifest
7. Registering a Background Task
var builder = new BackgroundTaskBuilder();
builder.Name = "TimeZoneTask";
builder.TaskEntryPoint = "SampleBackgroundTask.TimeZoneTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
builder.Register();
Recurring rather than one-shot
9. Unregistering a Background Task
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == "TimeZoneTask")
task.Value.Unregister(false);
}
Do not cancel instances of this
task that are currently executing
10.
11. Triggers
Background tasks run when triggers fire
And when conditions are satisfied (more later)
A background task must have exactly one trigger
Specified with BackgroundTaskBuilder.SetTrigger
Some triggers can be used by any app
SystemTrigger and MaintenanceTrigger
Others can only be used by lock-screen apps
TimerTrigger, PushNotificationTrigger, and ControlChannelTrigger
12. Trigger Types
Req’s Lock
Trigger Host Description
Screen?
System* Sometimes BTH See System Trigger Types
At most every 15 minutes on
Maintenance* No BTH
15 minute boundary; requires AC
Timer* Yes BTH Like Maintenance; can be on battery
PushNotification Yes BTH / App When WNS pushes raw payload
ControlChannel Yes App For RTC; not for JS
*Can be 1-shot or repeating
BTH == BackgroundTaskHost.exe process (default if not in manifest)
App ==App’s process
13. System Trigger Types
Types that don't require a lock screen
Type Description
InternetAvailable Internet becomes available
LockScreenApplicationAdded Your app is added to the lock screen
LockScreenApplicationRemoved Your app is removed from the lock screen
NetworkStateChange Network change occurs (e.g., cost change)
OnlineIdConnectedStateChange Online ID associated with the account changes
ServicingComplete Your app is updated
SmsReceived Device receives an SMS (text) message
TimeZoneChange Device's time zone changes
14. System Trigger Types, Cont.
Types that require a lock screen
Type Description
Fires when a control channel representing a real-time
ControlChannelReset network connection is reset and therefore might need to
be reestablished
SessionConnected Fires when the user logs in
Fires when a period of inactivity indicates user is "away"
UserAway
(e.g., when the screen blanks)
Fired when activity resumes, indicating user is present (e.g.,
UserPresent
when the mouse is wiggled)
15. Registering an App-Update Task
var builder = new BackgroundTaskBuilder();
builder.Name = "UpdateTask";
builder.TaskEntryPoint = "SampleBackgroundTask.AppUpdateTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.ServicingComplete));
builder.Register();
16. Registering a Periodic Task
// Register PeriodicTask to execute every 15 minutes
var builder = new BackgroundTaskBuilder();
builder.Name = "PeriodicTask";
builder.TaskEntryPoint = "SampleBackgroundTask.PeriodicTask";
builder.SetTrigger(new MaintenanceTrigger(15, false));
builder.Register();
Minimum 15 minutes Recurring rather than one-shot
17. Conditions
Background tasks can have conditions attached
Task runs when trigger fires and all conditions are met
Added with BackgroundTaskBuilder.AddCondition
Windows.ApplicationModel.Background.System-Condition class models
system conditions
Whether Internet is available
Whether user is logged in
Whether user is present
18. Condition Types
Type Description
InternetAvailable Runs background task if Internet is available
InternetNotAvailable Runs background task if Internet is not available
SessionConnected Runs background task if user is logged in
SessionDisconnected Runs background task if user is not logged in
UserNotPresent Runs background task if user is not present
UserPresent Runs background task if user is present
19. Adding a Condition
var builder = new BackgroundTaskBuilder();
builder.Name = "TimeZoneTask";
builder.TaskEntryPoint = "SampleBackgroundTask.TimeZoneTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
builder.Register();
20. Passing Data from a Task
Task writes data to ApplicationData
LocalSettings, LocalFolder, etc.
App retrieves data from ApplicationData
// Write result to LocalSettings in the background task
ApplicationData.Current.LocalSettings.Values["Result"] = result;
// Retrieve result from LocalSettings in the app (assumes result is a string)
var result = (string)ApplicationData.Current.LocalSettings.Values["Result"];
21.
22. Lock-Screen Apps
Apps that are added to the lock screen by users
Lock screen can display up to 7 apps
Apps display useful, at-a-glance, real-time information
Must implement background task using one of the following triggers,
which are only available to lock-screen apps
ControlChannelTrigger (always-connected RTC apps)
PushNotificationTrigger (receipt of raw notifications)
TimeTrigger (time-based, like MaintenanceTrigger)
Afforded higher QOS than normal apps
24. Making an App Lock-Screen Capable
Use Application UI tab in manifest editor to specify what the app is
capable of
Toast notifications, badge updates, tile-text updates
Tile-text updates require wide logo
App can display toast notifications
App can update badge and tile text
25. Lock-Screen Access
Only users can add apps to the lock screen
BackgroundExecutionManager provides API for checking for and
requesting lock-screen access
Type Description
GetAccessStatus Indicates whether app has access to lock screen
Prompts the user for access. Method is awaitable and returns
RequestAccessAsync BackgroundAccessStatus value. Prompts user one time;
subsequent invocations return user's previous decision.
RemoveAccess Removes an app from the lock screen
26. Checking for Lock-Screen Access
var result = BackgroundExecutionManager.GetAccessStatus();
switch (result)
{
case BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity:
break;
case BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity:
break;
case BackgroundAccessStatus.Denied:
break;
case BackgroundAccessStatus.Unspecified:
break;
}
27. Requesting Lock-Screen Access
var result = await BackgroundExecutionManager.RequestAccessAsync();
switch (result)
{
case BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity:
break;
case BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity:
break;
case BackgroundAccessStatus.Denied:
break;
case BackgroundAccessStatus.Unspecified:
break;
}
28. Using a TimeTrigger
var status = BackgroundExecutionManager.GetAccessStatus();
if (status == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity ||
status == BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity)
{
var builder = new BackgroundTaskBuilder();
builder.Name = "TimerTask";
builder.TaskEntryPoint = "SampleBackgroundTask.TimerTask";
builder.SetTrigger(new TimeTrigger(15, false));
builder.Register();
}
29. Updating a Lock-Screen Badge
// Display a numeric badge
var xml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);
((XmlElement)xml.GetElementsByTagName("badge")[0]).SetAttribute("value", "7");
var bu = BadgeUpdateManager.CreateBadgeUpdaterForApplication();
bu.Update(new BadgeNotification(xml));
// Display a glyph badge
var xml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeGlyph);
((XmlElement)xml.GetElementsByTagName("badge")[0]).SetAttribute("value", "newMessage");
var bu = BadgeUpdateManager.CreateBadgeUpdaterForApplication();
bu.Update(new BadgeNotification(xml));
30. Updating Lock-Screen Text
var xml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWideText05);
var text = xml.GetElementsByTagName("text");
text[0].InnerText = "Make awesome apps";
text[1].InnerText = "BUILD Conference";
text[2].InnerText = "9:00 AM - 11:00 AM";
var tu = TileUpdateManager.CreateTileUpdaterForApplication();
tu.Update(new TileNotification(xml));