トレーニング
ラーニング パス
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization
このブラウザーはサポートされなくなりました。
Microsoft Edge にアップグレードすると、最新の機能、セキュリティ更新プログラム、およびテクニカル サポートを利用できます。
重要な API
バックグラウンド タスク クラスを作成し、アプリがフォアグラウンドにない場合に実行するように登録します。 このトピックでは、アプリのプロセスとは別のプロセスで実行されるバックグラウンド タスクを作成して登録する方法について説明します。 フォアグラウンド アプリケーションでバックグラウンド処理を直接実行するには、「 作成してプロセス内のバックグラウンド タスクを登録する」を参照してください。
注意
バックグラウンド タスクを使ってバックグラウンドでメディアを再生する場合、Windows 10 バージョン 1607 で簡単に行うことができる機能強化について、「バックグラウンドでのメディアの再生」をご覧ください。
注意
.NET 6 以降を使用して C# デスクトップ アプリケーションでアウトプロセス バックグラウンド タスクを実装する場合は、C#/WinRT 作成サポートを使用してWindows ランタイム コンポーネントを作成します。 これは、Windows アプリ SDK、WinUI 3、WPF、または WinForms を使用するアプリに適用されます。 例については、 Background タスクのサンプル を参照してください。
IBackgroundTask インターフェイスを実装するクラスを記述することで、バックグラウンドでコードを実行できます。 このコードは、SystemTrigger や MaintenanceTrigger などを使って特定のイベントをトリガーすると実行されます。
次の手順では、 IBackgroundTask インターフェイスを実装する新しいクラスを記述する方法を示します。
注意
バックグラウンド タスク クラス自体と、バックグラウンド タスク プロジェクト内のその他すべてのクラスは、sealed (または final の) public クラスである必要があります。
次のサンプル コードは、バックグラウンド タスク クラスの基本的な開始点を示しています。
// 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)
{
}
非同期メソッドを呼び出す前に、Run メソッド内で遅延を要求します。 クラスのデータ メンバーに遅延を保存して、非同期メソッドからアクセスできるようにします。 非同期コードの完了後に遅延完了を宣言します。
次のサンプル コードでは、遅延を取得して保存し、非同期コードが完了した時点で解放します。
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 キーワードを使用して呼び出すことができます。 C++/CX では、タスク チェーンを使うことで同様の結果が得られます。
非同期パターンの詳細については、「 Asynchronous プログラミングを参照してください。 遅延を使用してバックグラウンド タスクを早期に停止させないようにする方法のその他の例については、 バックグラウンド タスクのサンプルを参照してください。
次の手順は、いずれかのアプリ クラス (たとえば、MainPage.xaml.cs) で完了します。
注意
バックグラウンド タスクを登録するための専用の関数を作成することもできます (「バックグラウンド タスクの登録」を参照)。 その場合、次の 3 つの手順は不要です。単にトリガーを作成し、タスクの名前とタスクのエントリ ポイント、(必要に応じて) 条件と併せて登録関数に渡すだけで済みます。
次の例では、AllTasks プロパティを反復処理し、タスクが既に登録されていた場合はフラグ変数を true に設定します。
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();
}
バックグラウンド タスク トリガーは、バックグラウンド タスクを実行するタイミングを制御します。 使用可能なトリガーの一覧については、 SystemTrigger を参照してください。
たとえば、こちらのコードでは、新しいバックグラウンド タスクを作成し、TimeZoneChanged トリガーが発生したときに実行されるように設定しています。
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));
次のサンプル コードでは、ユーザーが存在することを要求する条件を割り当てます。
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));
次のコードは、バックグラウンド タスクを登録し、結果を格納します。
BackgroundTaskRegistration task = builder.Register();
Windows::ApplicationModel::Background::BackgroundTaskRegistration task{ builder.Register() };
BackgroundTaskRegistration^ task = builder->Register();
注意
ユニバーサル Windows アプリは、どの種類のバックグラウンド トリガーを登録する場合でも、先に RequestAccessAsync を呼び出す必要があります。
更新プログラムをリリースした後もユニバーサル Windows アプリが引き続き正常に実行されるようにするには、 ServicingComplete ( SystemTriggerType を参照) トリガーを使用して、アプリのデータベースの移行やバックグラウンド タスクの登録などの更新後の構成変更を実行します。 現時点では、アプリの以前のバージョンに関連付けられているバックグラウンド タスクの登録を解除し ( RemoveAccess を参照)、新しいバージョンのアプリのバックグラウンド タスクを登録することをお勧めします ( RequestAccessAsync を参照)。
詳しくは、「バックグラウンド タスクのガイドライン」をご覧ください。
アプリがバックグラウンド タスクから結果を取得できるように、メソッドを BackgroundTaskCompletedEventHandler に登録する必要があります。 アプリが起動、または再開されると、アプリが最後にフォアグラウンドに置かれた後にバックグラウンド タスクが終了していた場合、指定のメソッドが呼び出されます (アプリが現在フォアグラウンドにある間にバックグラウンド タスクが完了すると、OnCompleted メソッドが直ちに呼び出されます)。
次のサンプル コードは、バックグラウンド タスクの完了を認識し、メッセージ文字列を受け取る UI 更新メソッドの例を呼び出します。
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 の更新を非同期的に実行する必要があります。 例については、 background タスク サンプルの UpdateUI メソッドを参照してください。
次のサンプル コードでは、 BackgroundTaskCompletedEventHandler を BackgroundTaskRegistration に追加します。
task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
task.Completed({ this, &MainPage::OnCompleted });
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &MainPage::OnCompleted);
アプリでバックグラウンド タスクを実行するには、アプリ マニフェストで各バックグラウンド タスクを宣言する必要があります。 マニフェストにないトリガーを使用してバックグラウンド タスクを登録しようとすると、バックグラウンド タスクの登録は、"ランタイム クラスが登録されていません" というエラーで失敗します。
次の Extensions 要素が Package.appxmanifest ファイルに追加され、バックグラウンド タスクが登録されます。
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="Tasks.ExampleBackgroundTask">
<BackgroundTasks>
<Task Type="systemEvent" />
</BackgroundTasks>
</Extension>
</Extensions>
バックグラウンド タスク クラスを記述する方法、アプリ内からバックグラウンド タスクを登録する方法、およびバックグラウンド タスクが完了したときにアプリで認識されるようにする方法の基本を理解する必要があります。 また、アプリがバックグラウンド タスクを正常に登録できるように、アプリケーション マニフェストを更新する方法についても理解する必要があります。
注意
バックグラウンド タスクのサンプルをダウンロードしてバックグラウンド タスクを使用する完全で堅牢な UWP アプリのコンテキストで同様のコード例を確認します。
API リファレンス、バックグラウンド タスクの概念ガイダンス、およびバックグラウンド タスクを使用するアプリを記述するための詳細な手順については、次の関連トピックを参照してください。
バックグラウンド タスクの詳細な説明トピック
バックグラウンド タスクのガイダンス
バックグラウンド タスク API リファレンス
トレーニング
ラーニング パス
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization
ドキュメント
タイマーでのバックグラウンド タスクの実行 - UWP applications
1 回限りのバックグラウンド タスクをスケジュールする方法、または定期的なバックグラウンド タスクを実行する方法について説明します。