Background process is used in different applications to perform various activities in the background, which doesn’t require any kind of user interaction. Mainly CPU centric long running processes are designed using the background process. Background processes have a significant role in Windows 8 Store app development compared to other areas. The requirement for background process arises due to the new process life cycle introduced in Store apps.
In this article we will discuss about the Windows Store Process life cycle and the importance of background process in Windows 8. We will look into few example scenarios like the background task implementation, background audio play and lock screen app in this article.
Windows Store App Process Lifetime management (PLM)
In traditional applications, user will decide the life cycle of an application like opens the app, switch to another app and terminates the application. In Windows 8, the process changed and Windows owns the app life cycle processes. User should not asked by dialogs to shut down or close the application. Even if the application crashes, user will not get any indication. There will be only one, maximum two applications runs on the foreground and all other apps look like running on background.
This foreground app holds the full access to CPU, Network and Memory resources, in which system can fully focus on one app and the resources are completely dedicated to the foreground app. This introduces the new process life cycle.
<shapetype o:preferrelative="t" o:spt="75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" coordsize="21600,21600" id="_x0000_t75"><stroke joinstyle="miter"><f eqn="if lineDrawn pixelLineWidth 0"><f eqn="sum @0 1 0"><f eqn="sum 0 0 @1"><f eqn="prod @2 1 2"><f eqn="prod @3 21600 pixelWidth"><f eqn="prod @3 21600 pixelHeight"><f eqn="sum @0 0 1"><f eqn="prod @6 1 2"><f eqn="prod @7 21600 pixelWidth"><f eqn="sum @8 21600 0"><f eqn="prod @7 21600 pixelHeight"><f eqn="sum @10 21600 0"><path o:connecttype="rect" o:extrusionok="f" gradientshapeok="t"><lock v:ext="edit" aspectratio="t"><shape o:spid="_x0000_i1037" type="#_x0000_t75" style="height: 156.75pt; visibility: visible; width: 269.25pt;" id="Picture_x0020_2"><imagedata src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png">
Figure 1: Process Life Cycle
Initially App will be in “Not Running” state. When the user invokes the app, it starts activating the app and displays the Splash screen followed by the app. When the user invokes another app to the foreground, current app will move to the suspended state. If the user invokes the app again to foreground, then it resumes the app with previous state. App terminates when the user close the app or the system will terminate due to low resource availability.
There are various events associated with the app state changes, which can be handled by the user. Developer can handle suspend and resume events and can process the app state information appropriately.
Code snippets to handle suspension and resume events.
public App() {
this.InitializeComponent();
this.Suspending += OnSuspending;
this.Resuming += App_Resuming;
}
void App_Resuming(object sender, object e)
{
throw new NotImplementedException();
}
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
await SuspensionManager.SaveAsync();
deferral.Complete();
}
There is no event associated with the app termination. We can check whether the app got terminated earlier through the activation event. Code snippet for verifying the previous state of the application
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
try
{
await SuspensionManager.RestoreAsync();
}
catch (SuspensionManagerException)
{
}
}
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
if (!rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups"))
{
throw new Exception("Failed to create initial page");
}
}
Window.Current.Activate();
}
Background Process
Even though, Windows Store process lifecycle demand for background process, there are lots of constraints associated with the Background process in Windows 8. All resources in Windows 8 allocated to the foreground process and allow limited access to various resources to the background process.
Background process can be either server side like Tile Push notification or can be at client side like background audio play, lock screen app, and so on. In this article we will look into the client side background process implementation using background tasks, background audio play and lock screen apps.
Background process runs irrespective of whether the main application is in running, suspended or terminated stage.
<shape type="#_x0000_t75" style="height: 105pt; visibility: visible; width: 468.75pt;" id="_x0000_i1036"><imagedata src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image002.png">
Figure 2: Background Process Life Cycle
Background Task Implementation
For implementing the background task, first create a main app which will be the foreground app. For our sample scenario, I am using an app which inserts few records to a database using WCF service.
<shape o:spid="_x0000_i1035" type="#_x0000_t75" style="height: 234pt; visibility: visible; width: 292.5pt;" id="Picture_x0020_4"><imagedata o:title="main screen" src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png">
Figure 3: Main app screen shot
Background task is the way in which we can perform background operations without bringing the app into foreground. For defining a background task, we need to define a WinRT component with the task class implementing the IBackgroundTask interface. This interface is having a single method- Run to do the background operation.
<shape o:spid="_x0000_i1034" type="#_x0000_t75" style="height: 281.25pt; visibility: visible; width: 391.5pt;" id="Picture_x0020_1"><imagedata src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image004.png">
Figure 4: WinRT Component Creation
Note: If we define the class inside normal class library project, then the background task will not work.
Sample Background task
Our main application will insert a record into the database using WCF Service. Background task polls the database in regular interval or depends on specified condition and see whether there is any new record in the table. If there is a new record, then process the new data.
using Windows.ApplicationModel.Background;
namespace MyBackgroundTask
{
public sealed class MyTask:IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
SampleSvc.Service1Client obj = new SampleSvc.Service1Client();
obj.ProcessDetailsAsync();
}
}
}
Registering Background Task
Add a reference of the background task project to the main app. Now register the background task in the main application by associate it with a trigger and condition.
Trigger
Trigger indicates when the task gets executed and there are a number of system defined triggers like TimeTrigger, MaintenanceTrigger, and so on. Foreground app register the trigger with system and when the trigger happened system will activate the background task inside the app container. For our sample scenario, we need the background task get executed depends on Internet available trigger to trigger the background process execution.
Condition
Condition defines the condition to execute the task and is optional. Even if the trigger launches the background task and if the condition is false, then the background task will not execute any code. Once the condition becomes true, it starts executing the task. There are system defined conditions like InternetAvailable, UserNotPresent, and so on. For our sample scenario, we are using the user present as a condition. Even though the internet is available, if the user is locked or another user logged into the system background task will not get executed.
<shape type="#_x0000_t75" style="height: 71.25pt; visibility: visible; width: 457.5pt;" id="_x0000_i1033"><imagedata src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image005.png">
Figure 5: Trigger and Condition
Code snippet to register the background task with our main application looks like
IBackgroundTaskRegistration task;
BackgroundTaskBuilder obj = new BackgroundTaskBuilder();
obj.Name = "MyBackgroundTask.MyTask";
obj.TaskEntryPoint = "MyBackgroundTask.MyTask";
SystemTrigger internetAvailable = new SystemTrigger(SystemTriggerType.InternetAvailable, false);
SystemCondition userCondition = new SystemCondition(SystemConditionType.UserPresent);
obj.SetTrigger(internetAvailable);
obj.AddCondition(userCondition);
task = obj.Register();
Capabilities or additional functionalities associated with any Windows 8 app needs to be specified inside the app manifest file. Now, we define the background tasks in the main app’s manifest file. Open the Package.manifest file and move to Declaration section. Add the Background task from the list. Select the trigger associated with the background task. Under app settings, set the entry point to the background task as our class which implements the IBackgroundTask interface.
<shape o:spid="_x0000_i1032" type="#_x0000_t75" style="height: 274.5pt; visibility: visible; width: 405pt;" id="Picture_x0020_7"><imagedata o:title="manifest" src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image006.png">
Figure 6: Background task declaration in Manifest
Progress Information
Main application can monitor the progress of the background task by setting the Progress property of IBackgroundTaskInstace inside the background task class. For getting the timely update in main application, register the Progress and Completed events of IBackgroundTaskRegistration.
Sample code snippet to pass the progress information from background task
public void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Progress = 0;
SampleSvc.Service1Client obj = new SampleSvc.Service1Client();
taskInstance.Progress = 20;
obj.ProcessDetailsAsync();
taskInstance.Progress = 100;
}
Sample code snippet to handle the progress and completed events in main application
BackgroundTaskRegistration task = obj.Register();
task.Progress += task_Progress;
task.Completed += task_Completed;
-----------------------------------
void task_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
{
status.Text = "Completed";
}
void task_Progress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args)
{
status.Text= "Progress - " + args.Progress +" %";
}
Background task registered in memory and is intact after suspension of the main application. Once the main application terminated, background task required re-registration. For re-registration, verify the background task existence using BackgroundTaskregistration.AllTasks.
If we are not verifying the existence of background task and simply register the same, then you can observe a number of background tasks with same name getting registered.
<shape o:spid="_x0000_i1031" type="#_x0000_t75" style="height: 202.5pt; visibility: visible; width: 224.25pt;" id="Picture_x0020_11"><imagedata o:title="bg verification" cropbottom="6158f" src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image007.png">
Figure 7: Multiple registration of the same background task
Verify the existence of the background task before registering the same.
IBackgroundTaskRegistration task;
if (BackgroundTaskRegistration.AllTasks.Count(t => t.Value.Name == "MyBackgroundTask.MyTask") ==0)
{
BackgroundTaskBuilder obj = new BackgroundTaskBuilder();
obj.Name = "MyBackgroundTask.MyTask";
obj.TaskEntryPoint = "MyBackgroundTask.MyTask";
SystemTrigger internetAvailable = new SystemTrigger(SystemTriggerType.InternetAvailable, false);
SystemCondition userCondition = new SystemCondition(SystemConditionType.UserPresent);
obj.SetTrigger(internetAvailable);
obj.AddCondition(userCondition);
task = obj.Register();
}
else
{
task=BackgroundTaskRegistration.AllTasks.Where(t => t.Value.Name == "MyBackgroundTask.MyTask").First().Value;
}
task.Progress += task_Progress;
task.Completed += task_Completed;
Integrating Background Task with Foreground
Foreground app and Backgroud task uses the same app settings including local and roaming settings. Communication between the foreground app and background tasks are through the app settings.
var localSetting =ApplicationData.Current.LocalSettings;
localSetting.Values["data"] = "Sample Data";
------------------------------------------
Object returnData = localSetting.Values["data"];
Testing and Debugging the Background Task
For debugging the background task, launch the main application first. Once the main application starts working in foreground, move to Visual Studio. Under the debug options, select the background task name to start debugging the background task.
<shape o:spid="_x0000_i1030" type="#_x0000_t75" style="height: 146.25pt; visibility: visible; width: 453pt;" id="Picture_x0020_8"><imagedata o:title="debug" src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image008.png">
Figure 8: Debugging background task
Note: - Above specified debug options are part of “Debug Location” tool bar
------------------------------------------------------------------------------------------------------------------------
Error: - When you start the debugging, you may get the following error message. Verify the background process task mentioned in two places
-entry point attribute specified in package manifest file
-entry point specified in main app while registering the background task
<shape o:spid="_x0000_i1029" type="#_x0000_t75" style="height: 138.75pt; visibility: visible; width: 357pt;" id="Picture_x0020_10"><imagedata o:title="err" src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image009.png">
Figure 9: Background task debug issue
Another option is to enable the Diagnostic log under Event Viewer-> Application and services log-> Microsoft-> Windows-> BackgroundTaskInfrastructure
------------------------------------------------------------------------------------------------------------------------
Once the above issue resolves, then the breakpoints will hit properly.
<shape o:spid="_x0000_i1028" type="#_x0000_t75" style="height: 289.5pt; visibility: visible; width: 456pt;" id="Picture_x0020_9"><imagedata o:title="debug bg" src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image010.png">
Figure 10: Background Task debugging
Lock Screen App
Using the Windows 8 store app, we can display some status information in the lock screen. Lock screen feature is especially useful in mobile application, where the device will be locked most of the time. Windows 8 lock screen consists of the background image, date and time, battery life indicator and the network status. An app can display its badge, latest tile notification from a live tile or a toast notification on the lock screen. We can display a maximum of 7 apps in the lock screen. Out of 7, one will display the text and the remaining can display either badge or toast notification.
Badge indicate a number from 0 to 99 or an icon, which indicate the new mails received, new twitter message count, stock market up or down, and so on. Tile notification will be a small text indicating the recent news, current market value, and so on. Toasts notifications are special notification appear on top right area of the screen, which stays in the screen for a specified interval. This will be a status update or an action required user intervention.
When a user place an app on lock screen indicates that the user likes to see the real time information from the app. Lock screen display the data from app’s start screen tile. If the tile is contains long text or not a live data, then the app may not be a good candidate for the lock screen.
App should declare the lock screen capability in the manifest file. We can select either badge or badge and tile text options in manifest file. If it is badge, then the app display the Badge logo along with the badge number. Otherwise, it use the wide logo specified in the manifest to display the badge and tile text.
Open the manifest file and move to Application UI tab. Specify the Badge logo and lock screen notification under the Notifications section.
<shape o:spid="_x0000_i1027" type="#_x0000_t75" style="height: 160.5pt; visibility: visible; width: 468pt;" id="Picture_x0020_3"><imagedata src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image011.png">
Figure 11: Lock screen declaration
For displaying the lock screen information, app must declare the background task under declarations. The background tasks supported by a lock screen app are Control Channel, Timer and Push Notification.
<shape o:spid="_x0000_i1026" type="#_x0000_t75" style="height: 193.5pt; visibility: visible; width: 468pt;" id="Picture_x0020_12"><imagedata src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image012.png">
Figure 12: Background task declaration
Send the badge update notification from the application using the tile notification. We can specify number from 0 to 99 or icon names like available, alert, etc. as badge value.
XmlDocument badgeXml = new XmlDocument();
badgeXml.LoadXml("<badge value=\"88\" />");
BadgeNotification badge = new BadgeNotification(badgeXml);
BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(badge);
There are two ways to enable the lock screen app to display in lock screen. One way is to request the user to place the app in lock screen by using “Background.BackgroundExecutionManager.RequestAccessAsync” method. This displays the user with a dialog box to requests that an app to be added to the lock screen. Or the user needs to manually enable it using PC Settings. Users have complete control of removing the lock screen app using the PC Settings.
<shape o:spid="_x0000_i1025" type="#_x0000_t75" style="height: 219.75pt; visibility: visible; width: 468pt;" id="Picture_x0020_13"><imagedata src="file:///C:\Users\Ambily\AppData\Local\Temp\msohtmlclip1\01\clip_image013.png">
Figure 13: Enabling the lock screen app
Conclusion
Background tasks have a major role in Windows 8 store app development. Windows 8 redefined the way apps interact with the system and users. Due to the limitation in number of foreground apps displayed and the concept of live tiles and lock screen apps demand the background tasks in many apps.