June 7, 2016 2:00 pm

Background activity with the Single Process Model

Interested in running your application in the background? A new developer option available in the Windows 10 Anniversary Update just made background activity a whole lot easier. Your feedback was clear on the multiple process model: while doing background work in a separate process was more resilient, it required significantly more code to implement. From this feedback we are able to provide a new option, a simplified method for enabling background activity without creating a background task. Now developers have the choice of running code in the background as either a separate process or directly inside the foreground application. We’ll cover the basics for all the tools which utilize the single process model:

  • Background Triggers
  • App Services
  • Background media playback using Activity Sponsored Execution.
  • Extended Execution

Let’s take a look at how the single process model is designed to make your life easier.

But first, the fundamentals

The single process model enhances the application lifecycle with improved notifications for when your app is in the foreground or in the background. Two new events are available from the Application object for these transitions: EnteredBackground and LeavingBackground. These events fit into the application lifecycle based on the visibility state of your application.

1_lifecycle

Entering the background

EnteredBackground lets your app know when it has moved out of foreground visibility completely. Previously the Suspending callback was the best place to save state after a user finished a session with your app. Now an application could continue running into the background and then move back to the foreground due to trigger activity without ever reaching the Suspended state. The best place to save data after a user session is in EnteredBackground. Memory limits also change as an app moves into the background. It is best to check the Memory Manager and drop memory if needed to ensure your app does not get terminated.

2_background

Leaving the background

Running in the background is the default state an application is activated or resumed into. Depending on the type of activation, your app may then move to running in the foreground or it may stay in the background. The LeavingBackground event is fired just before application UI is visible to your user. Previously the best location to load UI was in the Activated or Resuming event handlers. Now LeavingBackground is the best place to do your final checks that the UI is up and ready for presentation. It is important to check that visual assets are ready by this time, as this is the last opportunity to do work before your application is visible to the user.

Using EnteredBackground and LeavingBackground will allow your application to move smoothly between the foreground and background as a single process application.

Getting into the implementation

Now that we learned the fundamentals, let’s talk about actually doing the work.

  • Background triggers allow you to do work in your app
  • App services allows for other apps to use your app to do work.
  • Background media playback lets your app continue to play audio without being in the foreground and without a background audio task.

Background Triggers

Single process background activity is registered just like multiple process background activity. All background triggers start with registration using the Background Task Builder. The builder makes it easy to register a background task by setting all required values in one place.


var builder = new BackgroundTaskBuilder();
builder.Name = "My Background Trigger";
builder.SetTrigger(new TimeTrigger(15, true));

// use builder.TaskEntryPoint if you want to not use the default OnBackgroundActivated
// we’ll register it and now will start work based on the trigger, here we used a Time Trigger
BackgroundTaskRegistration task = builder.Register();


Register your background triggers with BackgroundTaskBuilder, but do not set the TaskEntryPoint. This will enable the default entry point, a new protected method on the Application object called OnBackgroundActivated. Once a trigger is registered, it can now fire based on the type of trigger set in the SetTrigger method. In the example above a TimeTrigger is used, which will fire fifteen minutes from the time it was registered. Taking action when that trigger fires can be accomplished by filling in the OnBackgroundActivated method. OnBackgroundActivated can be treated just like an IBackgroundTask’s Run method. The method has a parameter of BackgroundActivatedEventArgs, which contains everything that the Run method delivers.


 // Since we didn’t use TaskEntryPoint, this is the default constructor used
protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
            base.OnBackgroundActivated(args);
            DoBackgroundWork(args.TaskInstance);  
 }


The simplest way to convert your multiple process background activity into single process is to bring your IBackgroundTask Run method code inside your application and initiate it from OnBackgroundActivated. The code above assumes your app only has one background task. If your app has multiple background tasks the Background Activation Sample shows how you can use BackgroundActivatedEventArgs.TaskInstance.Task.Name to identify which task is being initiated. If you are currently communicating between background and foreground processes, you can remove that state management and communication code. Now background actions like database writes can be synced easily with your foreground application, because your application is actually performing the background activity.

App Services

While triggers are used to activate your application in the background from system activities, an App Service Connection enables another application to wake up your app in the background and start a direct line of communication. App Services do not run forever and are limited to the work that is requested by the foreground host application. This could be used to request information from an app or to hand off data for processing or ingestion by the App Service. App Services can now also be run in the same process as the foreground application making communication between apps much easier while removing the need to separate the service code to a separate project. With the introduction of App Services to the single process model two running foreground applications can have a direct line of communication via an App Service Connection. Turning a multiple process model App Service into single process model requires two changes. The first is a change in the manifest.


<uap:Extension Category="windows.appService">
          <uap:AppService Name="SingleProcessAppService" />
</uap:Extension>


Simply remove the EntryPoint attribute, like we did with BackgroundTaskBuilder. Now the same OnBackgroundActivated callback will be used as the callback method. The second change is to move the service logic from a separate IBackgroundTask project into methods that can be called from OnBackgroundActivated, just like we did with the Background Trigger conversion. Now your application can directly run your App Service!

private AppServiceConnection appServiceconnection;
private BackgroundTaskDeferral appServiceDeferral;
protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
    base.OnBackgroundActivated(args);
    IBackgroundTaskInstance taskInstance = args.TaskInstance;
    AppServiceTriggerDetails appService = taskInstance.TriggerDetails as AppServiceTriggerDetails;
    appServiceDeferral = taskInstance.GetDeferral();
    taskInstance.Canceled += OnAppServicesCanceled;
    appServiceConnection = appService.AppServiceConnection;
    appServiceConnection.RequestReceived += OnAppServiceRequestReceived;
    appServiceConnection.ServiceClosed += AppServiceConnection_ServiceClosed;
}
private async void OnAppServiceRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
    AppServiceDeferral messageDeferral = args.GetDeferral();
    ValueSet message = args.Request.Message;
    string text = message["Request"] as string;
            
    if ("Value" == text)
    {
        ValueSet returnMessage = new ValueSet();
        returnMessage.Add("Response", "True");
        await args.Request.SendResponseAsync(returnMessage);
    }
    messageDeferral.Complete();
}
private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
    appServiceDeferral.Complete();
}
private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
    appServiceDeferral.Complete();
}

In the code snippet above the OnBackgroundActivated method has been implemented to handle activation for an AppService. All of the events required for communication through an AppServiceConnection are registered, and the task deferral object is stored so that it can be marked as complete when the communication between the applications is done. In the example above an app receives a request and reads the ValueSet provided to see if the “Key” and “Value” strings are present. If they are present then the app service returns a pair of “Response” and “True” string values back to the app on the other side of the AppServiceConnection. You can learn more about connecting and communicating with other apps from Create and Consume an App Service.

Background Media Playback

Background media has a single process option which removes the need for inter-process communication and state management, saving hundreds of lines of code. Now playback can continue from the foreground to the background seamlessly with one simple addition: add the new background media playback capability to your manifest along with the new uap schema namespace, and that’s it.


<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  IgnorableNamespaces="uap uap3 mp">
...
<Capabilities>
<uap3:Capability Name="backgroundMediaPlayback"/>
</Capabilities>

All of the media playback APIs are available to you as you move from the foreground into the background, there is no more need to communicate to a BackgroundMediaPlayer in a separate process! With this form of sponsored background execution the system will see that your application is playing media and will automatically extend its lifetime as it moves into the background. To learn more, take a look at the Background Media Playback Sample.

Doing more work with Extended Execution

Extended Execution is a method to continue work being done in the foreground while an app moves into the background. If you have important work to complete, extended execution allows for a more time to complete that actions before the app moves into the suspended state. Rather than initiating background activity by registering a trigger for later activation, applications that are in the foreground and need to continue doing work in the background can use Extended Execution. An Extended Execution session acts as a lock that is requested for background activity.

When requesting extended execution there are five required steps:

  1. Create a new Extended Execution Session
  2. Set the Reason for the session
  3. Fill out the Description for what is occurring in the session
  4. Provide a revocation callback in case the session needs to be revoked early
  5. Make the request for the execution extension

ExtendedExecutionSession Session = new ExtendedExecutionSession();
Session.Reason = ExtendedExecutionReason.Unspecified;
Session.Description = BackgroundActivityDescription;
Session.Revoked += SessionRevoked;
ExtendedExecutionResult result = await Session.RequestExtensionAsync();


Your request could be denied, at which point you should decide whether you need to notify the user or perform a shorter action. Hold onto the session as long as your activity needs to occur; if it goes out of scope or is marked as disposed then your session will end. If you do not dispose it yourself your session will run until it has been revoked by the system and the Revoked event will fire. It is important to clean up and halt work quickly, or your application could be terminated.

An Extended Execution Session can be used for Saving Data, Location Tracking, or generic Unspecified scenarios. Each of these scenarios is expressed as an ExtendedExecutionReason, which is required for initiating the session. Each reason has a different amount of time to complete before the session is revoked. Location Tracking session can run as long as location tracking is required even when a device is entering a low power mode, while a Saving Data session runs for a limited time period before it is revoked. Unspecified Extended Execution has a battery-aware timeout. It can run as long as the user is interacting with the device while it is charging and plugged into power. If the device is running off of battery power it can run for a limited time, unless the user sets the “Always allowed in background” option for your app in the Battery Use Settings. This is a new setting available in the Windows 10 Anniversary Update for devices that have batteries to give users more choice around what apps can use energy in the background. More information on this behavior is available in the Extended Execution Sample.

Unsupported Scenarios

Background activity can still be terminated even when inside an app if it runs past execution time limits, so for some purposes the resiliency of separating work into a background task will still be useful. Keeping background work as a task separate from the foreground application may be the best option for work that does not require communication to the foreground application. There are a set of scenarios that are currently not supported with the single process model. DeviceUseTrigger, DeviceServicingTrigger and IoTStartupTask cannot be used with the single process model at this time. Activating a VoIP background task within your application is also not possible. These triggers and tasks are still supported using the multiple process model.

We are always listening to feedback and what the community is interested in us working on.  Please tell us via the Windows Platform UserVoice forum so we know what APIs are needed.

Wrapping Up

The Single Process Model is a new option available to developers targeting the Windows 10 Anniversary Update. Background activity isn’t needed for every app; the application lifecycle is often all you need to provide a rich experience for users. For those applications that do require background activity a single process app requires significantly less code to implement, and no more communication between multiple processes. The Background Task Sample shows that background activity can still be run in a separate process, but now background Triggers and App Services can be run alongside Extended Execution and audio playback directly inside your application.

Additional Resources:

Updated June 23, 2016 5:40 am

Join the conversation

  1. A separate project background task for more control based logic, a single project based background task for something as trivial as music playback. Saved me quite a lot of work.. Good going msft

  2. “Now LeavingBackground is the best place to do your final checks that the UI is up and ready for presentation.”

    This is true also if the application has no background or uses the two processes?

    • LeavingBackground is still the best place to do your final check that UI is ready, even if your app uses two processes for background activity or has no background activity. It is the last callback available before UI is shown, coming after OnLaunch or Resuming.

  3. Can someone here tell me how to do ‘Windows service’ type of stuff on windows phone?
    I mean, an independent background service that just does its work, like checking on some service every x seconds or something. But eventually even without the need of having a foreground UI app installed or running?
    Or is this only possible with push notifications?

  4. This is good as long as you target only Windows 10 1607. If you want to support also the old versions (1506 and 1511), your code will get messy quick easily.

  5. Still not as useful for Desktop as old good .exe files 🙂
    When you guyz will give us ability just work minimized on desktop!??? With your Windows RT you eliminated multi-treading and now slowly trying to give us something back? Beautiful strategy!
    I have box with 32gb ram and 12 core CPU and I cannot run Metro app to do it job when minimized because you are scare it can east my memory!? 🙂

    • Now apps can run when minimized on the desktop using the Extended Execution or Background Media Playback options listed in the blog post.

  6. Background Media Playback does not work with AudioGraph. If you guys know it does not work then tell us about it.

  7. So, now that I have Anniversary Update on my devices, I decided to rewrite my BackgroundMediaPlayer uwp app to use the new methodology. I love it! It works great! Except for the fact that I can’t build a package to put in the store as long as I have the “” line in my package.appxmanifest file. Anyone know how to get around this?

    • The “” was the line with “uap3:Capability Name=”backgroundMediaPlayback””. I didn’t take out the xml characters and I guess those (and everything between them) got deleted.

    • Never mind. I was going off of the sample that still states that we have to add the line to the app manifest manually. That’s not true anymore, so using the manifest designer fixed that.

  8. New Background Audio way is good only for fast and simple developing. On windows phone if you terminate your app, it will also terminate audio playback. Two-process playback not stop audio even main app terminated. And on pc app closing stops music. So at this time I don’t want to use one-process mode.

  9. Does this single process model also work with PushNotificationTrigger (i.e for raw notification).
    While implementing for Windows 10 anniversary edition (build 14393), a time trigger worked with single process model but raw notification when received in background is not triggering the OnBackgroundActivated Event.

    • Yes, the single process model works with PushNotificationTrigger. If you continue to have problems with getting Background Activated to fire please let me know and we can investigate further.