The next Win8 sample shows the general form of the background task contract for Windows 8 Metro applications.
There are two parts to implementing a background task for a Metro style application:
- Implement the IBackgroundTask interface (contract).
- Register the background task with the system so that Windows starts the task at the appropriate time.
The IBackgroundTask interface has only one method: Run(). The only parameter to Run() is an IBackgroundTaskInstance. Your background task will communicate with the Windows system through the IBackgroundTaskInstance. In this sample, the background task registers to receive the Cancelled event from the IBackgroundTaskInstance if it should stop working on the current problem. The background task also updates the IBackgroundTaskInstance.Progress property to notify the system of its progress on the current problem.
You can think of the IBackgroundTask.Run() method as similar to the Task.Run() method in today’s .NET environment: it’s the entry point for your background task.
Registering a background task in WinRT is a bit more involved. Remember that this background task is not the same as just running something asynchronously. Instead, these background tasks communicate with the OS, so that they can receive events while your application is suspended. For example, a Mail client will be awakened, check mail, then update its live tile periodically when suspended. That requires using the Windows system Background Task contract.
You register a Background Task in a few steps, using a BackgroundTaskBuilder object. There are several properties you need to set on the BackgroundTaskBuilder:
var builder = new BackgroundTaskBuilder();
builder.Name = name;
builder.TaskEntryPoint = taskEntryPoint;
builder.SetTrigger(trigger);
The name is simply a name you use to identify the task (uniquely) in your application. The TaskEntryPoint is the fully qualified class name for the type that implements IBackgroundTask.
The trigger specifies when the task should be started. Any of the event types you specify must also be specified in you application’s package manifest. If you don’t specify the event types, your registrations will fail.
Aside: Here the sample seems a bit of a kludgy demo. They trigger some of the tasks when the machine’s current TimeZone changes. That, I think, is just for demo purposes. It’s easy for you (as the user) to switch time zones, and make the background task start. The other scenarios use a timer, and start the background task every 50 ms. That’s closer to a production scenario, but a little short of a time span.
Once you’ve initialized the builder, you register the task:
BackgroundTaskRegistration task = builder.Register();
That BackgroundTaskRegistration object contains some additional APIs that you use to create and communication channels between your foreground task and your background task.
task.Progress += new BackgroundTaskProgressEventHandler(OnProgress);
task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
private void OnCompleted(IBackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs e)
{
//
// Update the UI with progress reported by the background task.
//
SampleDispatcher.InvokeAsync(CoreDispatcherPriority.Normal,
(task, args) =>
{
try
{
var taskCompletion = task as IBackgroundTaskRegistration;
var completionArgs = args.Context as BackgroundTaskCompletedEventArgs;
if ((taskCompletion != null) && (args != null))
{
if (completionArgs.Status != null)
throw completionArgs.Status;
var key = taskCompletion.TaskId.ToString();
var settings = ApplicationData.Current.LocalSettings;
switch (taskCompletion.Name)
{
case SampleBackgroundTaskName:
SampleBackgroundTaskStatus.Text = settings.Values[key].ToString();
break;
case SampleBackgroundTaskWithConditionName:
SampleBackgroundTaskWithConditionStatus.Text = settings.Values[key].ToString();
break;
case ServicingCompleteTaskName:
ServicingCompleteStatus.Text = settings.Values[key].ToString();
break;
case TimeTriggeredTaskName:
TimeTriggeredBackgroundTaskStatus.Text = settings.Values[key].ToString();
break;
}
}
}
catch (Exception ex)
{
Error.Text = ex.ToString();
}
},
sender,
e);
}
private void OnProgress(IBackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs e)
{
SampleDispatcher.InvokeAsync(CoreDispatcherPriority.Normal,
(task, args) =>
{
var taskRegistration = task as IBackgroundTaskRegistration;
var progressArgs = args.Context as BackgroundTaskProgressEventArgs;
if ((task != null) && (args != null))
{
switch (taskRegistration.Name)
{
case SampleBackgroundTaskName:
SampleBackgroundTaskProgress.Text = "Progress: " + progressArgs.Progress + "%";
break;
case SampleBackgroundTaskWithConditionName:
SampleBackgroundTaskWithConditionProgress.Text =
"Progress: " + progressArgs.Progress + "%";
break;
case ServicingCompleteTaskName:
ServicingCompleteProgress.Text = "Progress: " + progressArgs.Progress + "%";
break;
case TimeTriggeredTaskName:
TimeTriggeredBackgroundTaskProgress.Text = "Progress: " + progressArgs.Progress + "%";
break;
}
}
},
sender,
e);
}
}
Of course, if you can register background tasks, you probably want to unregister them and make them stop.
The sample unregisters the background task by looping through each task and removing the requested task by name:
foreach (var cur in BackgroundTaskRegistration.AllTasks)
{
if (cur.Value.Name == name)
cur.Value.Unregister(true);
}
I’m assuming that you can also unregister the task by using the BackgroundTaskRegistration returned by the original register task call.
The key points to this sample are that there is a contract for Background Tasks that enables the your application to be awakened by Windows to perform some functions in response to time, or system events.
The keys to this sample are that there is a contract you should follow if your application needs to do periodic work while suspended, or running in the background. By following that contract, you’ll find much of the infrastructure you need is built into the operating system.

Has sorta a WP7 feel to background tasks. Lamda’s also make this look so much nicer.