Windows App Model: Background Tasks

Leveraging the power of background operations for your Universal Windows Platform applications.

Introduction to Background Tasks

Background tasks are a core component of the Windows app model, enabling your Universal Windows Platform (UWP) applications to perform operations even when they are not actively running in the foreground. This allows for enhanced user experiences, such as timely updates, synchronized data, and responsive notifications.

Why Use Background Tasks?

Key Concepts

Task Registration

Before a background task can run, it must be registered with the system. This involves specifying the entry point (usually a specific class within your app) and the trigger that will initiate the task.

Triggers

Triggers define the events that will cause a background task to execute. Windows provides a variety of triggers, including:

  • TimeTrigger: For scheduled execution at specific times or intervals.
  • PushNotificationTrigger: For executing when a push notification arrives.
  • DeviceUseTrigger: For tasks that require specific hardware access (e.g., Bluetooth).
  • NetworkStateChangeTrigger: For tasks that should run when the network connection changes.
  • SystemCondition: For tasks that depend on system states like being connected to a broadband network or being charging.

Conditions

Conditions allow you to specify when a registered background task should actually run. These ensure that tasks only execute when it's appropriate and won't negatively impact the user experience or system performance. Common conditions include:

  • InternetAvailableCondition
  • SessionConnectedCondition
  • UserPresentCondition
  • DeviceBatteryNotLowCondition

EntryPoint

The EntryPoint property specifies the name of the background task's entry point class. This class must implement the IBackgroundTask interface and contain the logic that will be executed when the task is triggered.

Implementing a Background Task

To implement a background task, you typically follow these steps:

  1. Create a Background Task Project: Add a new "Windows Runtime Component" project to your solution. This component will contain your background task code.
  2. Implement IBackgroundTask: In your Runtime Component, create a class that implements the IBackgroundTask interface. This interface has a single method, Run(IBackgroundTaskInstance taskInstance), where your background logic resides.
  3. Register the Task: In your main UWP application, register the background task using BackgroundTaskBuilder. Specify the entry point, trigger, and any conditions.
  4. Handle Task Cancellation: Implement the OnCompleted event handler in your background task to manage its lifecycle and handle potential cancellations.

Example: Registering a Time Triggered Background Task


using Windows.ApplicationModel.Background;

public async void RegisterBackgroundTask()
{
    // Check if background tasks are already registered
    var registered = BackgroundTaskRegistration.AllTasks.Values.Any(task => task.Name == "MyTimeTask");

    if (!registered)
    {
        var builder = new BackgroundTaskBuilder();
        builder.TaskName = "MyTimeTask";
        builder.EntryPoint = "MyBackgroundTaskComponent.MyTask"; // Namespace.ClassName

        // Create a time trigger
        var timeTrigger = new TimeTrigger(15, false); // Trigger every 15 minutes, doesn't need to be maintained
        builder.SetTrigger(timeTrigger);

        // Add a condition: task runs only when device is charging
        var condition = new SystemCondition(SystemConditionType.BatteryStatus);
        builder.AddCondition(condition);

        // Register the background task
        var registeredTask = builder.Register();

        // You can attach event handlers for completion or cancellation here
        registeredTask.Completed += MyTask_Completed;
    }
}

private void MyTask_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
{
    // Handle task completion (e.g., update UI, log results)
    // Consider using a deferral if you need to do async work before the task truly finishes.
}

// In your main app, call RegisterBackgroundTask() when appropriate, e.g., on app launch.

Example: Background Task Entry Point


using Windows.ApplicationModel.Background;
using Windows.UI.Notifications;
using System;

namespace MyBackgroundTaskComponent
{
    public sealed class MyTask : IBackgroundTask
    {
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            // Get deferral to keep task running after the Run method returns
            var deferral = taskInstance.GetDeferral();

            try
            {
                // Your background task logic here
                // For example, fetching data or updating a tile

                var toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
                var toastTextElements = toastXml.GetElementsByTagName("text");
                toastTextElements[0].AppendChild(toastXml.CreateTextNode("Background Task Ran!"));
                toastTextElements[1].AppendChild(toastXml.CreateTextNode("Task executed successfully at " + DateTime.Now.ToLocalTime()));

                var toast = new ToastNotification(toastXml);
                ToastNotificationManager.CreateToastNotifier().Show(toast);

                // You can also access taskInstance.TriggerDetails for more info

            }
            catch (Exception ex)
            {
                // Log the error
            }
            finally
            {
                // Release the deferral when done
                deferral.Complete();
            }
        }
    }
}

Best Practices and Considerations

Further Reading