Criar e registrar uma tarefa em segundo plano fora do processo.Create and register an out-of-process background task

APIs importantesImportant APIs

Crie uma classe de tarefa em segundo plano e a registre para ser executada quando seu aplicativo não estiver em primeiro plano.Create a background task class and register it to run when your app is not in the foreground. Este tópico demonstra como criar e registrar uma tarefa em segundo plano que é executada em um processo separado do seu aplicativo.This topic demonstrates how to create and register a background task that runs in a separate process than your app's process. Para fazer o trabalho em segundo plano diretamente no aplicativo em primeiro plano, consulte Criar e registrar uma tarefa em segundo plano no processo.To do background work directly in the foreground application, see Create and register an in-process background task.

Observação

Se você usar uma tarefa em segundo plano para reproduzir mídia em segundo plano, consulte Reproduzir mídia em segundo plano para obter informações sobre os aprimoramentos no Windows 10, versão 1607, que tornam a tarefa mais fácil.If you use a background task to play media in the background, see Play media in the background for information about improvements in Windows 10, version 1607, that make it much easier.

Criar a classe de tarefa em segundo planoCreate the Background Task class

Você pode executar código em segundo plano criando classes que implementam a interface IBackgroundTask.You can run code in the background by writing classes that implement the IBackgroundTask interface. Esse código é executado quando um evento específico é disparado usando, por exemplo, SystemTrigger ou MaintenanceTrigger.This code runs when a specific event is triggered by using, for example, SystemTrigger or MaintenanceTrigger.

As seguintes etapas mostram como escrever uma nova classe que implementa a interface IBackgroundTask.The following steps show you how to write a new class that implements the IBackgroundTask interface.

  1. Crie um novo projeto para tarefas em segundo plano e adicione-o à sua solução.Create a new project for background tasks and add it to your solution. Para fazer isso, clique com o botão direito do mouse no nó da solução na Gerenciador de soluções e selecione Adicionar > novo projeto.To do this, right-click on your solution node in the Solution Explorer and select Add > New Project. Em seguida, selecione o tipo de projeto de componente Windows Runtime , nomeie o projeto e clique em OK.Then select the Windows Runtime Component project type, name the project, and click OK.
  2. Referencie o projeto das tarefa em segundo plano no projeto de aplicativo da Plataforma Universal do Windows (UWP).Reference the background tasks project from your Universal Windows Platform (UWP) app project. Para um aplicativo C# ou C++, em seu projeto de aplicativo, clique com o botão direito do mouse em referências e selecione Adicionar nova referência.For a C# or C++ app, in your app project, right-click on References and select Add New Reference. Em Solução, selecione Projetos e clique para selecionar o nome do seu projeto de tarefa em segundo plano e clique em Ok.Under Solution, select Projects and then select the name of your background task project and click Ok.
  3. Para o projeto tarefas em segundo plano, adicione uma nova classe que implemente a interface IBackgroundTask .To the background tasks project, add a new class that implements the IBackgroundTask interface. O método IBackgroundTask. Run é um ponto de entrada necessário que será chamado quando o evento especificado for disparado; Esse método é necessário em todas as tarefas em segundo plano.The IBackgroundTask.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.

Observação

A própria classe de tarefa em segundo plano — e todas as outras classes no projeto de tarefa em segundo plano — precisam ser classes públicas lacradas (ou finais).The background task class itself—and all other classes in the background task project—need to be public classes that are sealed (or final).

O código de exemplo a seguir mostra um ponto de partida muito básico para uma classe de tarefa em segundo plano.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)
        {
            
        }        
    }
}
// First, add ExampleBackgroundTask.idl, and then build.
// ExampleBackgroundTask.idl
namespace Tasks
{
    [default_interface]
    runtimeclass ExampleBackgroundTask : Windows.ApplicationModel.Background.IBackgroundTask
    {
        ExampleBackgroundTask();
    }
}

// ExampleBackgroundTask.h
#pragma once

#include "ExampleBackgroundTask.g.h"

namespace winrt::Tasks::implementation
{
    struct ExampleBackgroundTask : ExampleBackgroundTaskT<ExampleBackgroundTask>
    {
        ExampleBackgroundTask() = default;

        void Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance);
    };
}

namespace winrt::Tasks::factory_implementation
{
    struct ExampleBackgroundTask : ExampleBackgroundTaskT<ExampleBackgroundTask, implementation::ExampleBackgroundTask>
    {
    };
}

// ExampleBackgroundTask.cpp
#include "pch.h"
#include "ExampleBackgroundTask.h"

namespace winrt::Tasks::implementation
{
    void ExampleBackgroundTask::Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance)
    {
        throw hresult_not_implemented();
    }
}
// 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
        );
    };
}

// ExampleBackgroundTask.cpp
#include "ExampleBackgroundTask.h"

using namespace Tasks;

void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
{
}
  1. Se você executar um código assíncrono na sua tarefa em segundo plano, então ela precisará usar um adiamento.If you run any asynchronous code in your background task, then your background task needs to use a deferral. Se você não usar um adiamento, o processo de tarefa em segundo plano poderá ser encerrado inesperadamente se o método Run retornar antes de qualquer trabalho assíncrono ter sido executado até a conclusão.If you don't use a deferral, then the background task process can terminate unexpectedly if the Run method returns before any asynchronous work has run to completion.

Solicite o adiamento no método Run antes de chamar o método assíncrono.Request the deferral in the Run method before calling the asynchronous method. Salve o adiamento em um membro de dados de classe para que ele possa ser acessado do método assíncrono.Save the deferral to a class data member so that it can be accessed from the asynchronous method. Declare o adiamento como concluído após a conclusão do código assíncrono.Declare the deferral complete after the asynchronous code completes.

O código de exemplo a seguir obtém o adiamento, salva-o e libera-o quando o código assíncrono é concluído.The following sample code gets the deferral, saves it, and releases it when the asynchronous code is complete.

BackgroundTaskDeferral _deferral; // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation
public async void Run(IBackgroundTaskInstance taskInstance)
{
    _deferral = taskInstance.GetDeferral();
    //
    // TODO: Insert code to start one or more asynchronous methods using the
    //       await keyword, for example:
    //
    // await ExampleMethodAsync();
    //

    _deferral.Complete();
}
// ExampleBackgroundTask.h
...
private:
    Windows::ApplicationModel::Background::BackgroundTaskDeferral m_deferral{ nullptr };

// ExampleBackgroundTask.cpp
...
Windows::Foundation::IAsyncAction ExampleBackgroundTask::Run(
    Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance)
{
    m_deferral = taskInstance.GetDeferral(); // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation.
    // TODO: Modify the following line of code to call a real async function.
    co_await ExampleCoroutineAsync(); // Run returns at this point, and resumes when ExampleCoroutineAsync completes.
    m_deferral.Complete();
}
void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
{
    m_deferral = taskInstance->GetDeferral(); // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation.

    //
    // 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([=]() {
        m_deferral->Complete();
    });
}

Observação

Em C#, os métodos assíncronos da tarefa em segundo plano podem ser chamados usando as palavras-chave async/await.In C#, your background task's asynchronous methods can be called using the async/await keywords. No C++/CX, um resultado semelhante pode ser obtido usando uma cadeia de tarefas.In C++/CX, a similar result can be achieved by using a task chain.

Para mais informações sobre padrões assíncronos, consulte Programação assíncrona.For more information about asynchronous patterns, see Asynchronous programming. Para exemplos adicionais sobre como usar os adiamentos para evitar que uma tarefa em segundo plano pare antecipadamente, consulte a amostra de tarefa em segundo plano.For additional examples of how to use deferrals to keep a background task from stopping early, see the background task sample.

O procedimento abaixo é concluído em uma de suas classes de aplicativo (por exemplo, MainPage.xaml.cs).The following steps are completed in one of your app classes (for example, MainPage.xaml.cs).

Observação

Você também pode criar uma função dedicada ao registro de tarefas em segundo plano, — consulte registrar uma tarefa em segundo plano.You can also create a function dedicated to registering background tasks—see Register a background task. Nesse caso, em vez de usar as próximas três etapas, você pode simplesmente construir o gatilho e fornecê-lo à função de registro junto com o nome da tarefa, o ponto de entrada de tarefa e (opcionalmente) uma condição.In that case, instead of using the next three 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.

Registre a tarefa em segundo plano a ser executadaRegister the background task to run

  1. Descubra se a tarefa em segundo plano já está registrada Iterando por meio da propriedade BackgroundTaskRegistration. itempropertys.Find out whether the background task is already registered by iterating through the BackgroundTaskRegistration.AllTasks property. Esta etapa é importante; se seu aplicativo não verificar a existência de registros de tarefas em segundo plano, ele poderá facilmente registrar a tarefa várias vezes, causando problemas de desempenho e extrapolando o tempo de CPU disponível para a tarefa antes que esta possa ser concluída.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.

O exemplo a seguir itera na propriedade itempropertys e define uma variável de sinalizador como true se a tarefa já estiver registrada.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 BackgroundTaskRegistration.AllTasks)
{
    if (task.Value.Name == exampleTaskName)
    {
        taskRegistered = true;
        break;
    }
}
std::wstring exampleTaskName{ L"ExampleBackgroundTask" };

auto allTasks{ Windows::ApplicationModel::Background::BackgroundTaskRegistration::AllTasks() };

bool taskRegistered{ false };
for (auto const& task : allTasks)
{
    if (task.Value().Name() == exampleTaskName)
    {
        taskRegistered = true;
        break;
    }
}

// The code in the next step goes here.
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();
}
  1. Se a tarefa em segundo plano ainda não estiver registrada, use BackgroundTaskBuilder para criar uma instância de sua tarefa em segundo plano.If the background task is not already registered, use BackgroundTaskBuilder to create an instance of your background task. O ponto de entrada da tarefa deve ser o nome de sua classe de tarefa em segundo plano prefixada pelo namespace.The task entry point should be the name of your background task class prefixed by the namespace.

O gatilho da tarefa em segundo plano controla quando a tarefa será executada.The background task trigger controls when the background task will run. Para obter uma lista dos possíveis gatilhos, consulte SystemTrigger.For a list of possible triggers, see SystemTrigger.

Por exemplo, esse código cria uma nova tarefa em segundo plano e a define para ser executada quando ocorre o gatilho Timefusochanged :For example, this code creates a new background task and sets it to run when the TimeZoneChanged trigger occurs:

var builder = new BackgroundTaskBuilder();

builder.Name = exampleTaskName;
builder.TaskEntryPoint = "Tasks.ExampleBackgroundTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
if (!taskRegistered)
{
    Windows::ApplicationModel::Background::BackgroundTaskBuilder builder;
    builder.Name(exampleTaskName);
    builder.TaskEntryPoint(L"Tasks.ExampleBackgroundTask");
    builder.SetTrigger(Windows::ApplicationModel::Background::SystemTrigger{
        Windows::ApplicationModel::Background::SystemTriggerType::TimeZoneChange, false });
    // The code in the next step goes here.
}
auto builder = ref new BackgroundTaskBuilder();

builder->Name = exampleTaskName;
builder->TaskEntryPoint = "Tasks.ExampleBackgroundTask";
builder->SetTrigger(ref new SystemTrigger(SystemTriggerType::TimeZoneChange, false));
  1. Você pode adicionar uma condição para controlar quando sua tarefa será executada após a ocorrência de um evento de gatilho (opcional).You can add a condition to control when your task will run after the trigger event occurs (optional). Por exemplo, se você não quiser que a tarefa seja executada até que o usuário esteja presente, use a condição UserPresent.For example, if you don't want the task to run until the user is present, use the condition UserPresent. Para obter uma lista das possíveis condições, consulte SystemConditionType.For a list of possible conditions, see SystemConditionType.

O código de exemplo abaixo atribui uma condição que exige que o usuário esteja presente:The following sample code assigns a condition requiring the user to be present:

builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent));
builder.AddCondition(Windows::ApplicationModel::Background::SystemCondition{ Windows::ApplicationModel::Background::SystemConditionType::UserPresent });
// The code in the next step goes here.
builder->AddCondition(ref new SystemCondition(SystemConditionType::UserPresent));
  1. Registre a tarefa em segundo plano chamando o método Register no objeto BackgroundTaskBuilder.Register the background task by calling the Register method on the BackgroundTaskBuilder object. Armazene o resultado BackgroundTaskRegistration para que ele possa ser usado na próxima etapa.Store the BackgroundTaskRegistration result so it can be used in the next step.

O código a seguir registra a tarefa em segundo plano e armazena o resultado:The following code registers the background task and stores the result:

BackgroundTaskRegistration task = builder.Register();
Windows::ApplicationModel::Background::BackgroundTaskRegistration task{ builder.Register() };
BackgroundTaskRegistration^ task = builder->Register();

Observação

Os aplicativos Universais do Windows devem chamar RequestAccessAsync antes de registrar qualquer tipo de gatilho em segundo plano.Universal Windows apps must call RequestAccessAsync before registering any of the background trigger types.

Para garantir que seu aplicativo Universal do Windows continue sendo executado corretamente depois que você liberar uma atualização, use o gatilho ServicingComplete (veja SystemTriggerType) para realizar quaisquer alterações de configuração pós-atualização, como migrar do banco de dados do aplicativo e registrar tarefas em segundo plano.To ensure that your Universal Windows app continues to run properly after you release an update, use the ServicingComplete (see SystemTriggerType) trigger to perform any post-update configuration changes such as migrating the app's database and registering background tasks. É recomendável cancelar o registro de tarefas em segundo plano associadas à versão anterior do aplicativo (veja RemoveAccess) e registrar tarefas em segundo plano para a nova versão do aplicativo (veja RequestAccessAsync) neste momento.It is best practice to unregister background tasks associated with the previous version of the app (see RemoveAccess) and register background tasks for the new version of the app (see RequestAccessAsync) at this time.

Para obter mais informações, consulte Diretrizes para tarefas em segundo plano.For more information, see Guidelines for background tasks.

Manipular a conclusão da tarefa em segundo plano usando manipuladores de eventosHandle background task completion using event handlers

Registre um método com o BackgroundTaskCompletedEventHandler. Dessa forma, seu aplicativo poderá obter resultados da tarefa em segundo plano.You should register a method with the BackgroundTaskCompletedEventHandler, so that your app can get results from the background task. Quando o aplicativo for iniciado ou retomado, o método marcado será chamado se a tarefa em segundo plano tiver sido concluída desde a última vez em que o aplicativo estava em primeiro plano.When the app is launched or resumed, the marked method will be called if the background task has completed since the last time the app was in the foreground. (O método OnCompleted será chamado imediatamente se a tarefa em segundo plano for concluída enquanto o aplicativo estiver em primeiro plano.)(The OnCompleted method will be called immediately if the background task completes while your app is currently in the foreground.)

  1. Escreva um método OnCompleted para manipular a conclusão das tarefas em segundo plano.Write an OnCompleted method to handle the completion of background tasks. Por exemplo, o resultado da tarefa em segundo plano pode ocasionar uma atualização da interface do usuário.For example, the background task result might cause a UI update. O volume do método mostrado aqui é necessário para o método do manipulador de eventos OnCompleted, mesmo que este exemplo não use o parâmetro args.The method footprint shown here is required for the OnCompleted event handler method, even though this example does not use the args parameter.

O seguinte código de exemplo reconhece a conclusão da tarefa em segundo plano e chama um método de atualização de interface de usuário de exemplo que leva a cadeia de caracteres da mensagem.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 = Windows.Storage.ApplicationData.Current.LocalSettings;
    var key = task.TaskId.ToString();
    var message = settings.Values[key].ToString();
    UpdateUI(message);
}
void UpdateUI(winrt::hstring const& message)
{
    MyTextBlock().Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [=]()
    {
        MyTextBlock().Text(message);
    });
}

void OnCompleted(
    Windows::ApplicationModel::Background::BackgroundTaskRegistration const& sender,
    Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs const& /* args */)
{
    // You'll previously have inserted this key into local settings.
    auto settings{ Windows::Storage::ApplicationData::Current().LocalSettings().Values() };
    auto key{ winrt::to_hstring(sender.TaskId()) };
    auto message{ winrt::unbox_value<winrt::hstring>(settings.Lookup(key)) };

    UpdateUI(message);
}
void MainPage::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
    auto settings = ApplicationData::Current->LocalSettings->Values;
    auto key = task->TaskId.ToString();
    auto message = dynamic_cast<String^>(settings->Lookup(key));
    UpdateUI(message);
}

Observação

As atualizações da interface do usuário devem ser executadas assincronamente para evitar atraso do thread da interface do usuário.UI updates should be performed asynchronously, to avoid holding up the UI thread. Por exemplo, consulte o método UpdateUI no exemplo de tarefa em segundo plano.For an example, see the UpdateUI method in the background task sample.

  1. Retorne para onde você registrou a tarefa em segundo plano.Go back to where you registered the background task. Depois dessa linha de código, adicione um novo objeto BackgroundTaskCompletedEventHandler.After that line of code, add a new BackgroundTaskCompletedEventHandler object. Forneça o método OnCompleted como o parâmetro para o construtor BackgroundTaskCompletedEventHandler.Provide your OnCompleted method as the parameter for the BackgroundTaskCompletedEventHandler constructor.

O seguinte código de exemplo adiciona um BackgroundTaskCompletedEventHandler ao BackgroundTaskRegistration:The following sample code adds a BackgroundTaskCompletedEventHandler to the BackgroundTaskRegistration:

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

Declare no manifesto do aplicativo que seu aplicativo usa tarefas em segundo planoDeclare in the app manifest that your app uses background tasks

Antes de o seu aplicativo conseguir executar tarefas em segundo plano, você deve declarar cada tarefa em segundo plano no manifesto do aplicativo.Before your app can run background tasks, you must declare each background task in the app manifest. Se seu aplicativo tentar registrar uma tarefa em segundo plano com um gatilho que não está listado no manifesto, o registro da tarefa em segundo plano falhará com um erro "classe de tempo de execução não registrada".If your app attempts to register a background task with a trigger that isn't listed in the manifest, the registration of the background task will fail with a "runtime class not registered" error.

  1. Abra o designer de manifesto do pacote abrindo o arquivo chamado Package.appxmanifest.Open the package manifest designer by opening the file named Package.appxmanifest.
  2. Abra a guia Declarações.Open the Declarations tab.
  3. Na lista suspensa Declarações Disponíveis, selecione Tarefas em Segundo Plano e clique em Adicionar.From the Available Declarations drop-down, select Background Tasks and click Add.
  4. Marque a caixa de seleção Evento do sistema.Select the System event checkbox.
  5. Na caixa de texto ponto de entrada: , insira o namespace e o nome da sua classe de plano de fundo, que é para este exemplo é Tasks. ExampleBackgroundTask.In the Entry point: textbox, enter the namespace and name of your background class which is for this example is Tasks.ExampleBackgroundTask.
  6. Feche o designer de manifesto.Close the manfiest designer.

O seguinte elemento Extensions é adicionado ao arquivo Package.appxmanifest para registrar a tarefa em segundo plano:The following Extensions element is added to your Package.appxmanifest file to register the background task:

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

Resumo e próximas etapasSummary and next steps

Agora você deve compreender os fundamentos de como escrever uma classe de tarefa em segundo plano, como registrar a tarefa em segundo plano no aplicativo e como fazer o aplicativo reconhecer quando a tarefa em segundo plano é concluída.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. Você também deve saber atualizar o manifesto do aplicativo para que seu aplicativo possa registrar com êxito a tarefa em segundo plano.You should also understand how to update the application manifest so that your app can successfully register the background task.

Observação

Baixe o exemplo de tarefa em segundo plano para ver exemplos de código semelhantes, no contexto de um aplicativo UWP completo e robusto, que usa tarefas em segundo plano.Download the background task sample to see similar code examples in the context of a complete and robust UWP app that uses background tasks.

Veja os seguintes tópicos relacionados para obter referência de API, diretriz conceitual de tarefa em segundo plano e instruções mais detalhadas para escrever aplicativos que usam tarefas em segundo plano.See the following related topics for API reference, background task conceptual guidance, and more detailed instructions for writing apps that use background tasks.

Tópicos de instruções detalhadas de tarefa em segundo planoDetailed background task instructional topics

Diretrizes da tarefa em segundo planoBackground task guidance

Referência de API de tarefa em segundo planoBackground Task API Reference