Поделиться через


Quickstart: Create and 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]

Create a background task class and register it to run, providing functionality when your app is not in the foreground.

Prerequisites

  • Your app needs to do work in the background, and the work cannot be done using any other background functionality provided by the platform.

Create the Background Task class

You can run code in the background by writing classes that implement the IBackgroundTask interface. This code will run when a specific event is triggered by using, for example, SystemTrigger or MaintenanceTrigger.

The following steps show you how to write a new class that implements the IBackgroundTask interface. Before getting started, create a new project in your solution for background tasks. Add a new empty class for your background task and import the Windows.ApplicationModel.Background namespace.

  1. Create a new project for background tasks and add it to your solution. To do this, right-click on your solution and select Add->New Project. Then select the Windows Runtime Component project type, name the project, and click OK.

  2. Reference the background tasks project from your Windows Store app or Windows Phone app project.

    For a C++ app, right-click on your app project and select Properties. Then go to Common Properties and click Add New Reference, check the box next to your background tasks project, and click OK on both dialogs.

    For a C# app, in your app project, right click on References and select Add New Reference. Under Solution, select Projects and then select the name of your background task project and click Ok.

  3. Create a new class that implements the IBackgroundTask interface. The Run method is a required entry point that will be called when the specified event is triggered; this method is required in every background task.

    Note  The background task class itself - and all other classes in the background task project - need to be public classes that are sealed.

    The following sample code shows a very basic starting point for a background task class:

    //
    // ExampleBackgroundTask.cs
    //
    
    using Windows.ApplicationModel.Background;
    
    namespace Tasks
    {
        public sealed class ExampleBackgroundTask : IBackgroundTask
        {
            public void Run(IBackgroundTaskInstance taskInstance)
            {
    
            }        
        }
    }
    
    //
    // ExampleBackgroundTask.cpp
    //
    
    #include "ExampleBackgroundTask.h"
    
    using namespace Tasks;
    
    void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
    {
    
    }
    
    //
    // ExampleBackgroundTask.h
    //
    
    #pragma once
    
    using namespace Windows::ApplicationModel::Background;
    
    namespace Tasks
    {
        public ref class ExampleBackgroundTask sealed : public IBackgroundTask
        {
    
        public:
            ExampleBackgroundTask();
    
            virtual void Run(IBackgroundTaskInstance^ taskInstance);
            void OnCompleted(
                    BackgroundTaskRegistration^ task,
                    BackgroundTaskCompletedEventArgs^ args
                    );
        };
    }
    
  4. If you run any asynchronous code in your background task, then your background task needs to use a deferral. If you don't use a deferral, then the background task process can terminate unexpectedly if the Run method completes before your asynchronous method call has completed.

    Request the deferral in the Run method before calling the asynchronous method. Save the deferral to a global variable so it can be accessed from the asynchronous method. Declare the deferral complete after the asynchronous code completes.

    The following sample code gets the deferral, saves it, and releases it when the asynchronous code is complete:

    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
    
        //
        // TODO: Insert code to start one or more asynchronous methods using the
        //       await keyword, for example:
        //
        // await ExampleMethodAsync();
        //
    
        _deferral.Complete();
    }
    
    void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
    {
        BackgroundTaskDeferral^ deferral = taskInstance->GetDeferral();
    
        //
        // TODO: Modify the following line of code to call a real async function.
        //       Note that the task<void> return type applies only to async
        //       actions. If you need to call an async operation instead, replace
        //       task<void> with the correct return type.
        //
        task<void> myTask(ExampleFunctionAsync());
    
        myTask.then([=] () {
            deferral->Complete();
        });
    }
    

    Note  In C#, your background task's asynchronous methods can be called using the async/await keywords. In C++, a similar result can be achieved by using a task chain.

     

    For more information on asynchronous patterns, see Asynchronous programming. For additional examples of how to use deferrals to keep a background task from stopping early, see the background task sample.

The following steps are completed in one of your app classes (for example, MainPage.xaml.cs).

Note  You can also create a function dedicated to registering background tasks - see How to register a background task. In that case, instead of using the next 3 steps, you can simply construct the trigger and provide it to the registration function along with the task name, task entry point, and (optionally) a condition.

 

Register the background task to run

  1. Find out if the background task is already registered by iterating through the BackgroundTaskRegistration.AllTasks property. This step is important; if your app doesn't check for existing background task registrations, it could easily register the task multiple times, causing issues with performance and maxing out the task's available CPU time before work can complete.

    The following example iterates on the AllTasks property and sets a flag variable to true if the task is already registered:

    var taskRegistered = false;
    var exampleTaskName = "ExampleBackgroundTask";
    
    foreach (var task in Background.BackgroundTaskRegistration.AllTasks)
    {
        if (task.Value.Name == exampleTaskName)
        {
            taskRegistered = true;
            break;
        }
    }
    
    boolean taskRegistered = false;
    Platform::String^ exampleTaskName = "ExampleBackgroundTask";
    
    auto iter = BackgroundTaskRegistration::AllTasks->First();
    auto hascur = iter->HasCurrent;
    
    while (hascur)
    {
        auto cur = iter->Current->Value;
    
        if(cur->Name == exampleTaskName)
        {
            taskRegistered = true;
            break;
        }
    
        hascur = iter->MoveNext();
    }
    
  2. If the background task is not already registered, use BackgroundTaskBuilder to create an instance of your background task. The task entry point should be the name of your background task class prefixed by the namespace.

    The background task trigger controls when the background task will run. For a list of possible triggers, see SystemTrigger.

    For example, this code creates a new background task and sets it to run when the TimeZoneChanged trigger is fired:

    var builder = new BackgroundTaskBuilder();
    
    builder.Name = exampleTaskName;
    builder.TaskEntryPoint = "Tasks.ExampleBackgroundTask";
    builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
    
    auto builder = ref new BackgroundTaskBuilder();
    
    builder->Name = exampleTaskName;
    builder->TaskEntryPoint = "Tasks.ExampleBackgroundTask";
    builder->SetTrigger(ref new SystemTrigger(SystemTriggerType::TimeZoneChange, false));
    
  3. You can add a condition to control when your task will run after the trigger event occurs (optional). For example, if you don't want the task to run until the user is present, use the condition UserPresent. For a list of possible conditions, see SystemConditionType.

    The following sample code assigns a condition requiring the user to be present:

    builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent));
    
    builder->AddCondition(ref new SystemCondition(SystemConditionType::UserPresent));
    
  4. Register the background task by calling the Register method on the BackgroundTaskBuilder object. Store the BackgroundTaskRegistration result so it can be used in the next step.

    The following code registers the background task and stores the result:

    BackgroundTaskRegistration task = builder.Register();
    
    BackgroundTaskRegistration^ task = builder->Register();
    

    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).

    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.

     

Handle background task completion using event handlers

You should register a method with the BackgroundTaskCompletedEventHandler, so that your app can get results from the background task. When the app is launched or resumed, the OnCompleted method will be called if the background task has completed since the last time the app was in the foreground. (The OnCompleted method will be called immediately if the background task completes while your app is currently in the foreground.)

  1. Write an OnCompleted method to handle the completion of background tasks. For example, the background task result might cause a UI update. The method footprint shown here is required for the OnCompleted event handler method, even though this example does not use the args parameter.

    The following sample code recognizes background task completion and calls an example UI update method that takes a message string.

    private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args)
    {
        var settings = ApplicationData.Current.LocalSettings;
        var key = task.TaskId.ToString();
        var message = settings.Values[key].ToString();
        UpdateUIExampleMethod(message);
    }
    
    void ExampleBackgroundTask::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
    {
        auto settings = ApplicationData::Current->LocalSettings->Values;
        auto key = task->TaskId.ToString();
        auto message = dynamic_cast<String^>(settings->Lookup(key));
        UpdateUIExampleMethod(message);
    }
    

    Note  UI updates should be performed asynchronously, to avoid holding up the UI thread. For an example, see the UpdateUI method in the background task sample.

     

  2. Go back to where you registered the background task. After that line of code, add a new BackgroundTaskCompletedEventHandler object. Provide your OnCompleted method as the parameter for the BackgroundTaskCompletedEventHandler constructor.

    The following sample code adds a BackgroundTaskCompletedEventHandler to the BackgroundTaskRegistration:

    task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
    
    task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &ExampleBackgroundTask::OnCompleted);
    

Declare that your app uses background tasks in the app manifest

Before your app can run background tasks, you must declare each background task in the app manifest.

  • Open the app manifest (the file named "package.appmanifest") and go to the Extensions element. Add an Extension element, with category set to "windows.backgroundTasks", for each background task class used in your app.

    You must list each type of trigger used with your background task. If your app attempts to register a background task with a trigger that isn't listed in the manifest, the registration will fail.

    The following Extensions sample element registers the background task created in this topic:

    <Extensions>
      <Extension Category="windows.backgroundTasks" EntryPoint="Tasks.ExampleBackgroundTask">
        <BackgroundTasks>
          <Task Type="systemEvent" />
        </BackgroundTasks>
      </Extension>
    </Extensions>
    

Summary

You should now understand the basics of how to write a background task class, how to register the background task from within your app, and how to make your app recognize when the background task is complete. You should also understand how to update the application manifest so that Windows 8 will let your app register the background task.

Note  Download the background task sample to see similar code examples in the context of a complete and robust Windows Store app that uses background tasks.

 

See the following related topics for API reference, background task conceptual guidance, and more detailed instructions for writing apps that use background tasks.

Detailed background task instructional topics

How to respond to system events with background tasks

How to register a background task

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

Background task guidance

Guidelines and checklists for background tasks

How to debug a background task

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

Background Task API Reference

Windows.ApplicationModel.Background