Partilhar via


Registrar uma tarefa em segundo plano

APIs importantes

Aprenda a criar uma função que pode ser reutilizada para registrar com segurança a maioria das tarefas em segundo plano.

Este tópico é aplicável a tarefas em segundo plano no processo e tarefas em segundo plano fora do processo. Este tópico pressupõe que você já tenha uma tarefa em segundo plano que precisa ser registrada. (Veja Criar e registrar uma tarefa em segundo plano que é executada fora do processo ou Criar e registrar uma tarefa em segundo plano em processo para obter informações sobre como escrever uma tarefa em segundo plano).

Este tópico percorre uma função utilitária que registra tarefas em segundo plano. Essa função de utilitário verifica se há registros existentes antes de registrar a tarefa várias vezes para evitar problemas com vários registros e pode aplicar uma condição do sistema à tarefa em segundo plano. O passo a passo inclui um exemplo completo e funcional dessa função utilitária.

Observação  

Os aplicativos universais do Windows devem chamar RequestAccessAsync antes de registrar qualquer um dos tipos de gatilho em segundo plano.

Para garantir que seu aplicativo Universal do Windows continue a ser executado corretamente após o lançamento de uma atualização, você deve chamar RemoveAccess e, em seguida, chamar RequestAccessAsync quando seu aplicativo for iniciado após ser atualizado. Para obter mais informações, consulte Diretrizes para tarefas em segundo plano.

Definir a assinatura do método e o tipo de retorno

Esse método usa o ponto de entrada da tarefa, o nome da tarefa, um gatilho de tarefa em segundo plano pré-construído e (opcionalmente) um SystemCondition para a tarefa em segundo plano. Esse método retorna um objeto BackgroundTaskRegistration.

Importante

taskEntryPoint - Para tarefas em segundo plano que são executadas fora do processo, isso deve ser construído como o nome do namespace, '.', e o nome da classe que contém sua classe de plano de fundo. A cadeia de caracteres diferencia maiúsculas de minúsculas. Por exemplo, se você tivesse um namespace "MyBackgroundTasks" e uma classe "BackgroundTask1" que contivesse o código da classe em segundo plano, a cadeia de caracteres seria taskEntryPoint "MyBackgroundTasks.BackgroundTask1". Se a tarefa em segundo plano for executada no mesmo processo que o aplicativo (ou seja, uma tarefa em segundo plano em processo), taskEntryPoint não deverá ser definida.

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.

}

Verificar se há registros existentes

Verifique se a tarefa já está registrada. É importante verificar isso porque, se uma tarefa for registrada várias vezes, ela será executada mais de uma vez sempre que for acionada; isso pode usar excesso de CPU e pode causar um comportamento inesperado.

Você pode verificar se há registros existentes consultando a propriedade BackgroundTaskRegistration.AllTasks e iterando no resultado. Verifique o nome de cada instância – se corresponder ao nome da tarefa que você está registrando, saia do loop e defina uma variável de sinalizador para que seu código possa escolher um caminho diferente na próxima etapa.

Observação Use nomes de tarefas em segundo plano exclusivos do seu aplicativo. Verifique se cada tarefa em segundo plano tem um nome exclusivo.

O código a seguir registra uma tarefa em segundo plano usando o SystemTrigger que criamos na última etapa:

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

Registrar a tarefa em segundo plano (ou retornar o registro existente)

Verifique se a tarefa foi encontrada na lista de registros de tarefas em segundo plano existentes. Em caso afirmativo, retorne essa instância da tarefa.

Em seguida, registre a tarefa usando um novo objeto BackgroundTaskBuilder. Esse código deve verificar se o parâmetro de condição é nulo e, caso contrário, adicionar a condição ao objeto de registro. Retorne o BackgroundTaskRegistration retornado pelo método BackgroundTaskBuilder.Register.

Observação Os parâmetros de registro de tarefa em segundo plano são validados no momento do registro. Um erro será retornado se qualquer um dos parâmetros de registro for inválido. Certifique-se de que seu aplicativo lide normalmente com cenários em que o registro de tarefa em segundo plano falha – se, em vez disso, seu aplicativo depender de ter um objeto de registro válido depois de tentar registrar uma tarefa, ele poderá falhar. Observação Se você estiver registrando uma tarefa em segundo plano que é executada no mesmo processo que seu aplicativo, envie String.Empty ou null para o taskEntryPoint parâmetro.

O exemplo a seguir retorna a tarefa existente ou adiciona código que registra a tarefa em segundo plano (incluindo a condição opcional do sistema, se presente):

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;

    // in-process background tasks don't set TaskEntryPoint
    if ( taskEntryPoint != null && taskEntryPoint != String.Empty)
    {
        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;
}

Função completa do utilitário de registro de tarefas em segundo plano

Este exemplo mostra a função de registro de tarefa em segundo plano concluída. Essa função pode ser usada para registrar a maioria das tarefas em segundo plano, com exceção das tarefas em segundo plano de rede.

//
// 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;
}