How to register a background task (XAML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Learn how to create a function that can be re-used to safely register most background tasks. This topic walks through a utility function that registers background tasks. This utility function checks for existing registrations first before registering the task multiple times to avoid problems with multiple registrations, and it can apply a system condition to the background task. The walkthrough includes a complete, working example of this utility function.

Note  

For Windows Phone Store apps, you must call RequestAccessAsync before attempting to register any background task. On Windows, this call is only required for the set of background tasks that require your app to be on the lock screen to run, but on the phone you must call this method once before registering any background task.

To ensure that your Windows Phone Store app continues to run properly after you release an update, you must call RemoveAccess and then call RequestAccessAsync when your app launches after being updated. For more information, see Guidelines for background tasks (Windows Runtime apps).

What you need to know

Technologies

Prerequisites

  • This topic assumes that you already have a background task that needs to be registered (this topic doesn’t talk about how to write a background task).

Instructions

Step 1: Define the method signature and return type

This method takes in the task entry point, task name, a pre-constructed background task trigger, and (optionally) a SystemCondition for the background task. This method returns a BackgroundTaskRegistration object.

public static BackgroundTaskRegistration RegisterBackgroundTask(
                                                string taskEntryPoint, 
                                                string name,
                                                IBackgroundTrigger trigger,
                                                IBackgroundCondition condition)
{
    
    // We’ll add code to this function in subsequent steps.

}
BackgroundTaskRegistration^ MainPage::RegisterBackgroundTask(
                                             Platform::String ^ taskEntryPoint,
                                             Platform::String ^ taskName,
                                             IBackgroundTrigger ^ trigger,
                                             IBackgroundCondition ^ condition)
{
    
    // We’ll add code to this function in subsequent steps.

}

Step 2: Check for existing registrations

Check whether the task is already registered. It's important to check this because if a task is registered multiple times, it will run more than once whenever it’s triggered; this can use excess CPU quota and may cause unexpected behavior.

You can check for existing registrations by querying the BackgroundTaskRegistration.AllTasks property and iterating on the result. Check the name of each instance – if it matches the name of the task you’re registering, then break out of the loop and set a flag variable so that your code can choose a different path in the next step.

Note  Use background task names that are unique to your app. Ensure each background task has a unique name.

 

The following code registers a background task using the SystemTrigger we created in the last step:

public static BackgroundTaskRegistration RegisterBackgroundTask(
                                                string taskEntryPoint, 
                                                string name,
                                                IBackgroundTrigger trigger,
                                                IBackgroundCondition condition)
{
    //
    // Check for existing registrations of this background task.
    //

    foreach (var cur in BackgroundTaskRegistration.AllTasks)
    {

        if (cur.Value.Name == name)
        {
            // 
            // The task is already registered.
            // 

            return (BackgroundTaskRegistration)(cur.Value);
        }
    }


    // We’ll register the task in the next step.

}
BackgroundTaskRegistration^ MainPage::RegisterBackgroundTask(
                                             Platform::String ^ taskEntryPoint,
                                             Platform::String ^ taskName,
                                             IBackgroundTrigger ^ trigger,
                                             IBackgroundCondition ^ condition)
{

    //
    // Check for existing registrations of this background task.
    //
    
    auto iter   = BackgroundTaskRegistration::AllTasks->First();
    auto hascur = iter->HasCurrent;
    
    while (hascur)
    {
        auto cur = iter->Current->Value;
        
        if(cur->Name == name)
        {
            // 
            // The task is registered.
            // 
            
            return (BackgroundTaskRegistration ^)(cur);
        }
        
        hascur = iter->MoveNext();
    }


    // We’ll register the task in the next step.

}

Step 3: Register the background task (or return the existing registration)

Check to see if the task was found in the list of existing background task registrations. If so, return that instance of the task.

Then, register the task using a new BackgroundTaskBuilder object. This code should check whether the condition parameter is null, and if not, add the condition to the registration object. Return the BackgroundTaskRegistration returned by the BackgroundTaskBuilder.Register method.

Note  

Starting in Windows 8.1, background task registration parameters are validated at the time of registration. An error is returned if any of the registration parameters are invalid. Your app must be able to handle scenarios where background task registration fails - for example, use a conditional statement to check for registration errors and then retry failed registration using different parameter values.

 

The following example either returns the existing task, or adds code that registers the background task (including the optional system condition if present):

public static BackgroundTaskRegistration RegisterBackgroundTask(
                                                string taskEntryPoint, 
                                                string name,
                                                IBackgroundTrigger trigger,
                                                IBackgroundCondition condition)
{
    //
    // Check for existing registrations of this background task.
    //

    foreach (var cur in BackgroundTaskRegistration.AllTasks)
    {

        if (cur.Value.Name == taskName)
        {
            // 
            // The task is already registered.
            // 

            return (BackgroundTaskRegistration)(cur.Value);
        }
    }


    //
    // Register the background task.
    //

    var builder = new BackgroundTaskBuilder();

    builder.Name = name;
    builder.TaskEntryPoint = taskEntryPoint;
    builder.SetTrigger(trigger);

    if (condition != null)
    {

        builder.AddCondition(condition);
    }

    BackgroundTaskRegistration task = builder.Register();

    return task;
}
BackgroundTaskRegistration^ MainPage::RegisterBackgroundTask(
                                             Platform::String ^ taskEntryPoint,
                                             Platform::String ^ taskName,
                                             IBackgroundTrigger ^ trigger,
                                             IBackgroundCondition ^ condition)
{

    //
    // Check for existing registrations of this background task.
    //
    
    auto iter   = BackgroundTaskRegistration::AllTasks->First();
    auto hascur = iter->HasCurrent;
    
    while (hascur)
    {
        auto cur = iter->Current->Value;
        
        if(cur->Name == name)
        {
            // 
            // The task is registered.
            // 
            
            return (BackgroundTaskRegistration ^)(cur);
        }
        
        hascur = iter->MoveNext();
    }


    //
    // Register the background task.
    //

    auto builder = ref new BackgroundTaskBuilder();

    builder->Name = name;
    builder->TaskEntryPoint = taskEntryPoint;
    builder->SetTrigger(trigger);

    if (condition != nullptr) {
        
        builder->AddCondition(condition);
    }

    BackgroundTaskRegistration ^ task = builder->Register();

    return task;
}

Complete background task registration utility function

This example shows the completed background task registration function. This function can be used to register most background tasks, with the exception of networking background tasks.

//
// Register a background task with the specified taskEntryPoint, name, trigger,
// and condition (optional).
//
// taskEntryPoint: Task entry point for the background task.
// taskName: A name for the background task.
// trigger: The trigger for the background task.
// condition: Optional parameter. A conditional event that must be true for the task to fire.
//
public static BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint,
                                                                string taskName,
                                                                IBackgroundTrigger trigger,
                                                                IBackgroundCondition condition)
{
    //
    // Check for existing registrations of this background task.
    //

    foreach (var cur in BackgroundTaskRegistration.AllTasks)
    {

        if (cur.Value.Name == taskName)
        {
            // 
            // The task is already registered.
            // 

            return (BackgroundTaskRegistration)(cur.Value);
        }
    }


    //
    // Register the background task.
    //

    var builder = new BackgroundTaskBuilder();

    builder.Name = taskName;
    builder.TaskEntryPoint = taskEntryPoint;
    builder.SetTrigger(trigger);

    if (condition != null)
    {

        builder.AddCondition(condition);
    }

    BackgroundTaskRegistration task = builder.Register();

    return task;
}
//
// Register a background task with the specified taskEntryPoint, name, trigger,
// and condition (optional).
//
// taskEntryPoint: Task entry point for the background task.
// taskName: A name for the background task.
// trigger: The trigger for the background task.
// condition: Optional parameter. A conditional event that must be true for the task to fire.
//
BackgroundTaskRegistration^ MainPage::RegisterBackgroundTask(Platform::String ^ taskEntryPoint,
                                                             Platform::String ^ taskName,
                                                             IBackgroundTrigger ^ trigger,
                                                             IBackgroundCondition ^ condition)
{

    //
    // Check for existing registrations of this background task.
    //
    
    auto iter   = BackgroundTaskRegistration::AllTasks->First();
    auto hascur = iter->HasCurrent;
    
    while (hascur)
    {
        auto cur = iter->Current->Value;
        
        if(cur->Name == name)
        {
            // 
            // The task is registered.
            // 
            
            return (BackgroundTaskRegistration ^)(cur);
        }
        
        hascur = iter->MoveNext();
    }


    //
    // Register the background task.
    //

    auto builder = ref new BackgroundTaskBuilder();

    builder->Name = name;
    builder->TaskEntryPoint = taskEntryPoint;
    builder->SetTrigger(trigger);

    if (condition != nullptr) {
        
        builder->AddCondition(condition);
    }

    BackgroundTaskRegistration ^ task = builder->Register();

    return task;
}

Quickstart: Create and register a background task

How to respond to system events with background tasks

How to set conditions for running a background task

How to use maintenance triggers

How to handle a cancelled background task

How to monitor background task progress and completion

How to run a background task on a timer

How to debug a background task

How to trigger suspend, resume, and background events in Windows Store apps (when debugging)