註冊背景工作Register a background task

重要 APIImportant APIs

了解如何建立可重複用來安全登錄大多數背景工作的函式。Learn how to create a function that can be re-used to safely register most background tasks.

本主題同時適用於同處理序背景工作與跨處理序背景工作。This topic is applicable to both in-process background tasks and out-of-process background tasks. 本主題假設您已經有一個需要註冊的背景工作。This topic assumes that you already have a background task that needs to be registered. (請參閱建立及註冊在跨處理序中執行的背景工作建立及註冊同處理序背景工作了解如何撰寫背景工作的資訊)。(See Create and register a background task that runs out-of-process or Create and register an in-process background task for information about how to write a background task).

本主題會逐步解說可註冊背景工作的公用程式函式。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  

通用 Windows app 必須先呼叫 RequestAccessAsync,才能登錄任何背景觸發程序類型。Universal Windows apps must call RequestAccessAsync before registering any of the background trigger types.

為了確保您的通用 Windows app 會在您發行更新之後繼續正常執行,您必須呼叫 RemoveAccess,然後在 app 於更新後啟動時呼叫 RequestAccessAsyncTo ensure that your Universal Windows 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.

定義方法簽章和傳回類型Define the method signature and return type

這個方法會採用背景工作的工作進入點、工作名稱、預先建構的背景工作觸發程序,以及 (選用) SystemConditionThis method takes in the task entry point, task name, a pre-constructed background task trigger, and (optionally) a SystemCondition for the background task. 這個方法會傳回 BackgroundTaskRegistration 物件。This method returns a BackgroundTaskRegistration object.

重要

taskEntryPoint -對於在進程外執行的背景工作,必須將其視為命名空間名稱 '. ',以及包含背景類別的類別名稱。taskEntryPoint - for background tasks that run in out of process, this must be constructed as the namespace name, '.', and the name of the class containing your background class. 此字串區分大小寫。The string is case-sensitive. 例如,如果您有 "MyBackgroundTasks" 命名空間和包含您背景類別程式碼的 "BackgroundTask1" 類別,則 taskEntryPoint 的字串會是 "MyBackgroundTasks.BackgroundTask1"。For example, if you had a namespace "MyBackgroundTasks" and a class "BackgroundTask1" that contained your background class code, the string for taskEntryPoint would be "MyBackgroundTasks.BackgroundTask1". 如果您的背景工作與您的應用程式在相同處理序中執行 (亦即同處理序背景工作),就不應該設定 taskEntryPointIf your background task runs in the same process as your app (i.e. a in-process background task) taskEntryPoint should not be set.

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.

}

檢查是否有現有的註冊Check for existing registrations

檢查工作是否已登錄。Check whether the task is already registered. 這是檢查的重點,因為如果多次登錄工作,則觸發該工作時,它就會多次執行;這樣可能會過量使用 CPU,也可能造成未預期的行為。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 and may cause unexpected behavior.

您可以查詢 BackgroundTaskRegistration.AllTasks 屬性並逐一查看結果,以檢查現有登錄。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.

下列程式碼會使用我們在上一個步驟中建立的 SystemTrigger 來登錄背景工作: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.
}

登錄背景工作 (或傳回現有登錄)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.

然後使用新的 BackgroundTaskBuilder 物件登錄工作。Then, register the task using a new BackgroundTaskBuilder object. 這段程式碼應該會檢查條件參數是否為 Null;如果不是,則將條件新增到登錄物件。This code should check whether the condition parameter is null, and if not, add the condition to the registration object. 傳回由 BackgroundTaskBuilder.Register 方法傳回的 BackgroundTaskRegistrationReturn the BackgroundTaskRegistration returned by the BackgroundTaskBuilder.Register method.

注意   在註冊時,會驗證背景工作註冊參數。Note  Background task registration parameters are validated at the time of registration. 如果有任一個登錄參數無效,就會傳回錯誤。An error is returned if any of the registration parameters are invalid. 請確認您的 App 能夠妥善處理背景工作註冊失敗的狀況;反之,如果 App 需依賴有效的驗證物件,則在嘗試註冊工作之後,可能會當機。Ensure that your app gracefully handles scenarios where background task registration fails - if instead your app depends on having a valid registration object after attempting to register a task, it may crash. 注意:如果您要登錄與您 App 在相同處理程序中執行的背景工作,請針對 taskEntryPoint 參數傳送 String.EmptynullNote If you are registering a background task that runs in the same process as your app, send String.Empty or null for the taskEntryPoint parameter.

下列範例會傳回現有工作,或新增可登錄背景工作的程式碼 (如果有選擇性的系統條件,則也包括在內):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;

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

完成背景工作登錄公用程式函式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;
}