How to monitor background task progress and completion (XAML)
[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]
Learn how your app can recognize progress and completion reported by a background task. Background tasks are decoupled from the app, and they run separately, but background task progress and completion can be monitored by app code. To make this happen, the app subscribes to events from the background task(s) it has registered with the system.
What you need to know
Technologies
Prerequisites
- This topic assumes that you have an app that registers background tasks. To get started quickly building a background task, see Quickstart: Create and register a background task. For more in-depth information on conditions and triggers, see Support your app with background tasks.
Instructions
Step 1:
Create an event handler function to handle completed background tasks. This code needs to follow a specific footprint, which takes in an IBackgroundTaskRegistration object and a BackgroundTaskCompletedEventArgs object.
Use the following footprint for the OnCompleted background task event handler method:
private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args) { // TODO: Add code that deals with background task completion. }
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args) { // TODO: Add code that deals with background task completion. };
Add code to the event handler that deals with the background task completion.
For example, the background task sample updates the UI with the completion status saved in LocalSettings:
private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args) { var settings = ApplicationData.Current.LocalSettings; var key = task.TaskId.ToString(); BackgroundTaskSample.SampleBackgroundTaskStatus = settings.Values[key].ToString(); UpdateUI(); }
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args) { UpdateUI(); };
A robust app can check for exceptions thrown by the background task by calling CheckResult.
The background task sample can be modified as follows to handle exceptions thrown by the background task:
private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args) { var settings = ApplicationData.Current.LocalSettings; var key = task.TaskId.ToString(); try { args.CheckResult(); BackgroundTaskSample.SampleBackgroundTaskStatus = settings.Values[key].ToString(); } catch (Exception ex) { BackgroundTaskSample.SampleBackgroundTaskStatus = "Error: " + ex.Message; } UpdateUI(); }
auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args) { auto settings = ApplicationData::Current->LocalSettings; auto key = task->TaskId.ToString(); try { args->CheckResult(); } catch (Platform::Exception ^ ex) { auto settings = ApplicationData::Current->LocalSettings->Values; auto name = task->Name->ToString(); if (settings->HasKey(name)) { String^ status = ex->ToString(); settings->Insert(name, status); } } UpdateUI(); };
Step 2:
Create an event handler function to handle completed background tasks. This code needs to follow a specific footprint, which takes in an IBackgroundTaskRegistration object and a BackgroundTaskProgressEventArgs object:
Use the following footprint for the OnProgress background task event handler method:
private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args) { // TODO: Add code that deals with background task progress. }
auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args) { // TODO: Add code that deals with background task progress. };
Add code to the event handler that deals with the background task completion.
For example, the background task sample updates the UI with the progress status passed in via the args parameter:
private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args) { var progress = "Progress: " + args.Progress + "%"; BackgroundTaskSample.SampleBackgroundTaskProgress = progress; UpdateUI(); }
auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args) { auto progress = "Progress: " + args->Progress + "%"; BackgroundTaskSample::SampleBackgroundTaskProgress = progress; UpdateUI(); };
Step 3:
Register the event handler functions with new and existing background tasks.
When the app registers a background task for the first time, it should register to receive progress and completion updates for it, in case the task runs while the app is still active in the foreground.
For example, the background task sample calls the following function on each background task that it registers:
private void AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration task) { task.Progress += new BackgroundTaskProgressEventHandler(OnProgress); task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted); }
void SampleBackgroundTask::AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration^ task) { auto progress = [this](BackgroundTaskRegistration^ task, BackgroundTaskProgressEventArgs^ args) { auto progress = "Progress: " + args->Progress + "%"; BackgroundTaskSample::SampleBackgroundTaskProgress = progress; UpdateUI(); }; task->Progress += ref new BackgroundTaskProgressEventHandler(progress); auto completed = [this](BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args) { UpdateUI(); }; task->Completed += ref new BackgroundTaskCompletedEventHandler(completed); }
When the app launches, or navigates to a new page where background task status is relevant, it should get a list of background tasks currently registered and associate them with the progress and completion event handler functions. The list of background tasks currently registered by the application is kept in the BackgroundTaskRegistration.AllTasks property.
For example, the background task sample uses the following code to attach event handlers when the SampleBackgroundTask page is navigated to:
protected override void OnNavigatedTo(NavigationEventArgs e) { foreach (var task in BackgroundTaskRegistration.AllTasks) { if (task.Value.Name == BackgroundTaskSample.SampleBackgroundTaskName) { AttachProgressAndCompletedHandlers(task.Value); BackgroundTaskSample.UpdateBackgroundTaskStatus(BackgroundTaskSample.SampleBackgroundTaskName, true); } } UpdateUI(); }
void SampleBackgroundTask::OnNavigatedTo(NavigationEventArgs^ e) { // A pointer back to the main page. This is needed if you want to call methods in MainPage such // as NotifyUser() rootPage = MainPage::Current; // // Attach progress and completed handlers to any existing tasks. // auto iter = BackgroundTaskRegistration::AllTasks->First(); auto hascur = iter->HasCurrent; while (hascur) { auto cur = iter->Current->Value; if (cur->Name == SampleBackgroundTaskName) { AttachProgressAndCompletedHandlers(cur); break; } hascur = iter->MoveNext(); } UpdateUI(); }
Related topics
Quickstart: Create and register a background task
How to register a background task
How to get a list of pending background tasks
How to handle a cancelled background task
How to declare background tasks in the application manifest