Saturday, 27 September 2014

Background Task

In a winRT app it's all or nothing, that is to say that if you app isn't visible it's not running, No background polling, no heartbeat, nothing for all intensive purposes you can assume your app is in a suspended state in which nothing is happening. However, there is hope in something called a background task, now this background task runs in a restricted environment with limited resources, but beggars can't be choosers.

Needless to say but they should really only be used to fire small bits of code to inform your user of something and not used for any heavy lifting.

To get started you're going to have to add a WinMD project to your solution.

with that done add a reference from your Application Project to the WinMD project.

in the above the Application project is pc.Background and the WinMD project is pc.BackgorundTask, with your reference made open up the only class in your WinMD Project, it should look pretty bare bones.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace pc.BackgroundTask
{
    public sealed class Class1
    {
    }
}


Now let's change it from Class1 to something a little more descriptive, where going to fire background task when the application is added to the lock screen. so lets rename Class1 to AppendedToLockScreenBackgroundTask, with that change we are also going to have to implement the IBackgroundTask interface, it only implements one method and it's Run, this is the method that will asynchronously fire. I mention Asynchronously because we're going to have to grab a deferral to keep our Background task from falling out of scope before we fire our code.

with our changes complete we should have something along the lines of

using Windows.ApplicationModel.Background;

namespace pc.BackgroundTask
{
    public sealed class AppendedToLockScreenBackgroundTask : IBackgroundTask
    {
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            var deferral = taskInstance.GetDeferral();

            //Our Logic goes here

            deferral.Complete();
        }
    }
}


Now what to do, for now lets do something very simple and just add a toast notification, refer to my previous post on Toast's to add the logic.

With our Background Task, written we now need to go back to our application project and add some declarations into our manifest, so open up the "Package.appxmanifest" file and go to the declarations tab. Once there add the Background Tasks declaration specify the System Event and set the Entry Point to the Namespace.Class that implements your Run method

Now that's done, go back to the Application Tab and Set the Lock screen notification to Badge
and set the Toast Capable to Yes

Next you'll have to add the visual assets for badge notifications, i just made min in MS Paint,

Now with all that configuration out of the way let's register our background Task, open up your MainPage.xaml View and in the constructor register the event

//check to make sure that your background task isn't already registred
if (BackgroundTaskRegistration.AllTasks.FirstOrDefault(t => t.Value.Name == "AppendToLockScreen").Value == null)
{
    var builder = new BackgroundTaskBuilder();
    builder.Name = "AppendToLockScreen";
    builder.TaskEntryPoint = "pc.BackgroundTask.AppendedToLockScreenBackgroundTask";
    builder.SetTrigger(new SystemTrigger(SystemTriggerType.LockScreenApplicationAdded, false));

    var taskRegistration = builder.Register();

}

The above code registers the background event, now whenever the user adds the application to the Lock screen, it'll fire our toast notification.