アウトプロセス バックグラウンド タスクの作成と登録Create and register an out-of-process background task

重要な APIImportant APIs

バックグラウンド タスク クラスを作り、アプリがフォアグラウンドにない場合にも実行されるように登録します。Create a background task class and register it to run when your app is not in the foreground. このトピックでは、アプリのプロセスとは別のプロセスで実行されるバックグラウンド タスクを作成して登録する方法について説明します。This topic demonstrates how to create and register a background task that runs in a separate process than your app's process. フォアグラウンド アプリケーションで直接バックグラウンド作業を実行する方法については、「インプロセス バックグラウンド タスクの作成と登録」をご覧ください。To do background work directly in the foreground application, see Create and register an in-process background task.

注意

バックグラウンド タスクを使ってバックグラウンドでメディアを再生する場合、Windows 10 バージョン 1607 で簡単に行うことができる機能強化について、「バックグラウンドでのメディアの再生」をご覧ください。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.

バックグラウンド タスク クラスを作るCreate the Background Task class

IBackgroundTask インターフェイスを実装するクラスを作ると、コードをバックグラウンドで実行できます。You can run code in the background by writing classes that implement the IBackgroundTask interface. 次のコード実行など、特定のイベントを使用すると、トリガーされたときに SystemTrigger または MaintenanceTriggerします。This code runs when a specific event is triggered by using, for example, SystemTrigger or MaintenanceTrigger.

次の手順では、IBackgroundTask インターフェイスを実装する新しいクラスを記述する方法について説明します。The following steps show you how to write a new class that implements the IBackgroundTask interface.

  1. バックグラウンド タスク用に新しいプロジェクトを作ってソリューションに追加します。Create a new project for background tasks and add it to your solution. これを行うには、ソリューション ノードを右クリックし、ソリューション エクスプ ローラー選択追加 > 新しいプロジェクトします。To do this, right-click on your solution node in the Solution Explorer and select Add > New Project. 選択し、 Windows ランタイム コンポーネントプロジェクトの種類と、プロジェクトの名前、[ok] をクリックします。Then select the Windows Runtime Component project type, name the project, and click OK.
  2. ユニバーサル Windows プラットフォーム (UWP) アプリ プロジェクトからバックグラウンド タスク プロジェクトを参照します。Reference the background tasks project from your Universal Windows Platform (UWP) app project. C#を右クリックし、アプリ プロジェクトでの C++ アプリまたは参照選択新しい参照の追加します。For a C# or C++ app, in your app project, right-click on References and select Add New Reference. [ソリューション] で、 [プロジェクト] を選び、バックグラウンド タスク プロジェクトの名前を選んで [OK] をクリックします。Under Solution, select Projects and then select the name of your background task project and click Ok.
  3. バック グラウンド タスク プロジェクトに実装する新しいクラスを追加、 IBackgroundTask インターフェイス。To the background tasks project, add a new class that implements the IBackgroundTask interface. IBackgroundTask.Run メソッドは、指定したイベントがトリガーされたときに呼び出される必要なエントリ ポイントは、すべてのバック グラウンド タスクにこのメソッドが必要です。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.

注意

バック グラウンド タスク クラス自体—とバック グラウンド タスクのプロジェクトで他のすべてのクラス—する必要があるパブリッククラスシール(または最終).The background task class itself—and all other classes in the background task project—need to be public classes that are sealed (or final).

次のサンプル コードでは、バック グラウンド タスクのクラスの場合は、非常に基本的な開始点を示します。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. バックグラウンド タスクで非同期コードを実行する場合は、バックグラウンド タスクで遅延を使う必要があります。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 returns before any asynchronous work has run to completion.

要求で遅延、実行メソッドが非同期のメソッドを呼び出す前にします。Request the deferral in the Run method before calling the asynchronous method. 非同期メソッドからアクセスできるように、クラスのデータ メンバーに、遅延を保存します。Save the deferral to a class data member so that 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.

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();
    });
}

注意

C# では、async/await キーワードを使ってバックグラウンド タスクの非同期メソッドを呼び出すことができます。In C#, your background task's asynchronous methods can be called using the async/await keywords. C++/cli CX、タスクのチェーンを使用して、同様の結果を実現できます。In C++/CX, a similar result can be achieved by using a task chain.

非同期パターンについて詳しくは、「非同期プログラミング」をご覧ください。For more information about 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.

次の手順はいずれかのアプリ クラス (MainPage.xaml.cs など) で実行します。The following steps are completed in one of your app classes (for example, MainPage.xaml.cs).

注意

専用のバック グラウンド タスクを登録する関数を作成することもできます。—を参照してくださいバック グラウンド タスクを登録します。You can also create a function dedicated to registering background tasks—see Register a background task. その場合は、次の 3 つの手順を使用する代わりに単に、トリガーを構築できタスク名、タスクのエントリ ポイント、および (必要に応じて) 条件と共に登録関数に提供できます。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.

実行するバックグラウンド タスクを登録するRegister the background task to run

  1. 反復処理するバック グラウンド タスクが既に登録されているかどうかを調べる、 BackgroundTaskRegistration.AllTasks プロパティ。Find out whether the background task is already registered by iterating through the BackgroundTaskRegistration.AllTasks property. この確認は重要です。既にあるバックグラウンド タスクの二重登録をアプリで確認しなかった場合、同じタスクが何度も登録され、パフォーマンスが低下したり、タスクの CPU 時間を使い切って処理を完了できなくなるなどの問題が生じます。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.

次の例を反復処理、 AllTasksプロパティおよびタスクは既に登録されている場合は true にフラグ変数を設定します。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. バックグラウンド タスクがまだ登録されていない場合は、BackgroundTaskBuilder を使ってバックグラウンド タスクのインスタンスを作成します。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. 指定できるトリガーの一覧については、「SystemTrigger」をご覧ください。For a list of possible triggers, see SystemTrigger.

たとえば、このコードは新しいバック グラウンド タスクを作成し、時に実行するように設定、 TimeZoneChangedトリガーが発生します。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. トリガー イベントの発生後、どのようなときにタスクを実行するかという条件を追加することもできます (省略可能)。You can add a condition to control when your task will run after the trigger event occurs (optional). たとえば、ユーザーが存在するときにだけタスクを実行する場合、UserPresent という条件を使います。For example, if you don't want the task to run until the user is present, use the condition UserPresent. 指定できる条件の一覧については、「SystemConditionType」をご覧ください。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(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. BackgroundTaskBuilder オブジェクトで Register メソッドを呼び出してバックグラウンド タスクを登録します。Register the background task by calling the Register method on the BackgroundTaskBuilder object. BackgroundTaskRegistration の結果は、次の手順に備えて保存します。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();
Windows::ApplicationModel::Background::BackgroundTaskRegistration task{ builder.Register() };
BackgroundTaskRegistration^ task = builder->Register();

注意

ユニバーサル Windows アプリは、どの種類のバックグラウンド トリガーを登録する場合でも、先に RequestAccessAsync を呼び出す必要があります。Universal Windows apps must call RequestAccessAsync before registering any of the background trigger types.

更新プログラムのリリース後にユニバーサル Windows アプリが引き続き適切に実行されるようにするには、ServicingComplete (SystemTriggerType に関するページをご覧ください) トリガーを使って、アプリのデータベースの移行やバックグラウンド タスクの登録などの更新後の構成の変更を実行します。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. 現時点で、アプリの以前のバージョンに関連付けられたバックグラウンド タスクの登録を解除してから (RemoveAccess に関するページをご覧ください)、アプリの新しいバージョンのバックグラウンド タスクを登録する (RequestAccessAsync に関するページをご覧ください) ことをお勧めします。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.

詳しくは、「バックグラウンド タスクのガイドライン」をご覧ください。For more information, see Guidelines for background tasks.

イベント ハンドラーでバックグラウンド タスクの完了を処理するHandle background task completion using event handlers

アプリからバックグラウンド タスクの結果を取得できるように、BackgroundTaskCompletedEventHandler にメソッドを登録します。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 marked method will be called if the background task has completed since the last time the app was in the foreground. (アプリがフォアグラウンドにある間にバックグラウンド タスクが終了した場合は、OnCompleted メソッドが直ちに呼び出されます)。(The OnCompleted method will be called immediately if the background task completes while your app is currently in the foreground.)

  1. バックグラウンド タスクの完了を処理する OnCompleted メソッドを記述します。Write an OnCompleted method to handle the completion of background tasks. たとえば、バックグラウンド タスクの結果により UI を更新できます。For example, the background task result might cause a UI update. ここに示すメソッドのフットプリントは、この例では args パラメーターは使われていませんが、OnCompleted イベント ハンドラー メソッドで必須になります。The method footprint shown here is required for the OnCompleted event handler method, even though this example does not use the args parameter.

次のサンプル コードは、バックグラウンド タスクの完了を認識し、メッセージ文字列を使う UI 更新メソッドの例を呼び出します。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);
}

注意

UI の更新は、UI スレッドを拘束することがないように、非同期で実行する必要があります。UI updates should be performed asynchronously, to avoid holding up the UI thread. 例については、バックグラウンド タスクのサンプルの UpdateUI メソッドを参照してください。For an example, see the UpdateUI method in the background task sample.

  1. バックグラウンド タスクを登録した位置に戻ります。Go back to where you registered the background task. そのコード行の後に、新しい BackgroundTaskCompletedEventHandler オブジェクトを追加します。After that line of code, add a new BackgroundTaskCompletedEventHandler object. BackgroundTaskCompletedEventHandler コンストラクターのパラメーターとして OnCompleted メソッドを指定します。Provide your OnCompleted method as the parameter for the BackgroundTaskCompletedEventHandler constructor.

次のサンプル コードにより、BackgroundTaskRegistrationBackgroundTaskCompletedEventHandler が追加されます。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 in the app manifest that your app uses background tasks

アプリでバックグラウンド タスクを実行する前に、各バックグラウンド タスクをアプリ マニフェストで宣言する必要があります。Before your app can run background tasks, you must declare each background task in the app manifest. アプリがトリガーのあるマニフェストの一覧にないバック グラウンド タスクを登録しようとすると、バック グラウンド タスクの登録は「クラスのランタイムに登録されていません」エラーで失敗します。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. Package.appxmanifest という名前のファイルを開いて、パッケージ マニフェスト デザイナーを開きます。Open the package manifest designer by opening the file named Package.appxmanifest.
  2. [宣言] タブを開きます。Open the Declarations tab.
  3. [使用可能な宣言] ボックスの一覧の [バックグラウンド タスク] を選び、 [追加] をクリックします。From the Available Declarations drop-down, select Background Tasks and click Add.
  4. [システム イベント] チェック ボックスをオンにします。Select the System event checkbox.
  5. エントリ ポイント: テキスト ボックスに、この例は 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. マニフェスト デザイナーを閉じます。Close the manfiest designer.

バック グラウンド タスクを登録するために、次の Extensions 要素が Package.appxmanifest ファイルに追加されます。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>

要約と次のステップSummary and next steps

ここでは、バックグラウンド タスク クラスの記述方法、アプリ内からバックグラウンド タスクを登録する方法、バックグラウンド タスクが完了したことをアプリで認識する方法の基本について学習しました。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 your app can successfully register the background task.

注意

バックグラウンド タスクのサンプルをダウンロードして、バックグラウンド タスクを使う完全で堅牢な UWP アプリのコンテキストで類似のコード例を確認してください。Download the background task sample to see similar code examples in the context of a complete and robust UWP app that uses background tasks.

API リファレンス、バックグラウンド タスクの概念的ガイダンス、バックグラウンド タスクを使ったアプリの作成に関する詳しい説明については、次の関連するトピックをご覧ください。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

バック グラウンド タスクのガイダンスBackground task guidance

バック グラウンド タスクの API リファレンスBackground Task API Reference