Compartir a través de


Registrar una tarea en segundo plano

API importantes

Aprende a crear una función que pueda reutilizarse para registrar de forma segura la mayoría de las tareas en segundo plano.

Este tema es aplicable tanto a las tareas en segundo plano en proceso como a las tareas en segundo plano fuera de proceso. En este tema se supone que ya tiene una tarea en segundo plano que debe registrarse. (Consulte Cree y registre una tarea en segundo plano que se ejecute fuera de proceso o Crear y registrar una tarea en segundo plano en proceso para obtener información sobre cómo escribir una tarea en segundo plano).

En este tema se explica una función de utilidad que registra tareas en segundo plano. Esta función de utilidad comprueba primero los registros existentes antes de registrar la tarea varias veces para evitar problemas con varios registros y puede aplicar una condición del sistema a la tarea en segundo plano. El tutorial incluye un ejemplo completo y funcional de esta función de utilidad.

Note  

Las aplicaciones universales de Windows deben llamar a RequestAccessAsync antes de registrar cualquiera de los tipos de desencadenador en segundo plano.

Para asegurarse de que la aplicación universal de Windows sigue ejecutándose correctamente después de publicar una actualización, debes llamar a RemoveAccess y, a continuación, llamar a RequestAccessAsync cuando la aplicación se inicie después de actualizarse. Para obtener más información, vea Directrices para tareas en segundo plano.

Definir la firma del método y el tipo de valor devuelto

Este método toma el punto de entrada de la tarea, el nombre de la tarea, un desencadenador de tareas en segundo plano creado previamente y, opcionalmente, una SystemCondition para la tarea en segundo plano. Este método devuelve un objeto BackgroundTaskRegistration.

Importante

taskEntryPoint : para las tareas en segundo plano que se ejecutan fuera del proceso, se debe construir como el nombre del espacio de nombres, "." y el nombre de la clase que contiene la clase en segundo plano. La cadena distingue mayúsculas de minúsculas. Por ejemplo, si tenía un espacio de nombres "MyBackgroundTasks" y una clase "BackgroundTask1" que contenía el código de clase en segundo plano, la cadena de taskEntryPoint sería "MyBackgroundTasks.BackgroundTask1". Si la tarea en segundo plano se ejecuta en el mismo proceso que la aplicación (es decir, una tarea en segundo plano en proceso) taskEntryPoint no debe establecerse.

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.

}

Comprobación de registros existentes

Compruebe si la tarea ya está registrada. Es importante comprobar esto porque si una tarea se registra varias veces, se ejecutará más de una vez cada vez que se desencadene; esto puede usar un exceso de CPU y puede provocar un comportamiento inesperado.

Para comprobar si hay registros existentes, consulte la propiedad BackgroundTaskRegistration.AllTasks y realice una iteración en el resultado. Compruebe el nombre de cada instancia: si coincide con el nombre de la tarea que está registrando, divida el bucle y establezca una variable de marca para que el código pueda elegir una ruta de acceso diferente en el paso siguiente.

Nota Use nombres de tareas en segundo plano que sean únicos para la aplicación. Asegúrese de que cada tarea en segundo plano tenga un nombre único.

El código siguiente registra una tarea en segundo plano mediante SystemTrigger que creamos en el último paso:

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 la tarea en segundo plano (o devolver el registro existente)

Compruebe si la tarea se encontró en la lista de registros de tareas en segundo plano existentes. Si es así, devuelva esa instancia de la tarea.

A continuación, registre la tarea mediante un nuevo objeto BackgroundTaskBuilder. Este código debe comprobar si el parámetro condition es null y, si no es así, agregar la condición al objeto de registro. Devuelve backgroundTaskRegistration devuelto por el método BackgroundTaskBuilder.Register.

Nota Los parámetros de registro de tareas en segundo plano se validan en el momento del registro. Se devuelve un error si alguno de los parámetros de registro no es válido. Asegúrese de que la aplicación controla correctamente los escenarios en los que se produce un error en el registro de tareas en segundo plano; en su lugar, la aplicación depende de tener un objeto de registro válido después de intentar registrar una tarea, puede bloquearse. Nota Si va a registrar una tarea en segundo plano que se ejecuta en el mismo proceso que la aplicación, envíe String.Empty o null para el taskEntryPoint parámetro .

En el ejemplo siguiente se devuelve la tarea existente o se agrega código que registra la tarea en segundo plano (incluida la condición opcional del sistema si está 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;
}

Función completa de la utilidad de registro de tareas en segundo plano

En este ejemplo se muestra la función de registro de tareas en segundo plano completada. Esta función se puede usar para registrar la mayoría de las tareas en segundo plano, a excepción de las tareas en segundo plano de red.

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