Universal Windows 10 Apps – Background Tasks

Universal Windows 10 Apps – Background Tasks

BackgroundTasks1_1

Short introduction

Nowadays mobile applications with foreground functionality are something normal. Each app has User Interface where you can perform some actions and see results. But somethimes this is not enough. Sometimes we need our application to run some code in background. That’s why we need Background Task here. In this post I will show how to use them.

The whole source code is available on my Git Hub account.

What do I need to start?

1) Visual Studio 2015 Community (for free) or higher

Let’s start

1) Open Visual Studio and create new blank Universal App project:

BackgroundTasks2

2) Add Windows Runtime Component to the Solution:

It is worth to mention here what Windows Runtime Component is.

You can imagine that Component is a self-contained object that you can instantiate and use from C#, Visual Basci, JavaScript and C++. It is like independent container with some peace of code.

Right click on the Solution and select “Windows Runtime Component”:

BackgroundTasks3

BackgroundTasks4

3) Add reference to the Runtime Component from your UWP app:

BackgroundTasks5

BackgroundTasks6

4) Rename default class from Windows Runtime Component project to “BackgroundTaskSample”:

BackgroundTasks8

BackgroundTaskSample class has to implement IBackgroundTask interface. Add it to the code like below:

 public sealed class BackgroundTaskSample : IBackgroundTask
 {
    public void Run(IBackgroundTaskInstance taskInstance)
    {
      throw new NotImplementedException();
    }
 }

As you can see “Run” method is required to perform background operations.

It it also very important to mention here that if you plan to perform any asynchronous code in your background task you should use a defferal. Defferal is just a time that is provided to preform some operations. We will use it in the “GetStringFromURL” method:

 public sealed class BackgroundTaskSample : IBackgroundTask
 {
   BackgroundTaskDeferral _deferral;
   public void Run(IBackgroundTaskInstance taskInstance)
    {
      GetStringFromURL(taskInstance);
    }
 }

Here is how “GetStringFromURL()” looks like. Once execution of the background method is finished toast notification should appear with the string content retrieved:

 async void GetStringFromURL(IBackgroundTaskInstance taskInstance)
 {
    _deferral = taskInstance.GetDeferral();
    HttpClient client = new HttpClient();
    using (HttpResponseMessage response = await client.GetAsync("http://jsonplaceholder.typicode.com/posts/1"))
    using (HttpContent content = response.Content)
     {
       string result = await content.ReadAsStringAsync();
       DoToast(result);
     };
    _deferral.Complete();
 }

//Show toast notification with retrieved string content:
 private void DoToast(string stringContent)
 {
   ToastNotifier ToastNotifier = ToastNotificationManager.CreateToastNotifier();
   Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
   Windows.Data.Xml.Dom.XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text");
   toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode("Background tasks Sample"));
   toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(stringContent));
   Windows.Data.Xml.Dom.IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
   Windows.Data.Xml.Dom.XmlElement audio = toastXml.CreateElement("audio");
   audio.SetAttribute("src", "ms-winsoundevent:Notification.SMS");

   ToastNotification toast = new ToastNotification(toastXml);
   ToastNotifier.Show(toast);
 }

 

5) Register Background Task:

Let’s get back to our UWP application project. Here we should create class responsible for registering and controlling background tasks.

a. Add new folder called “BackgroundTasksHandlers” to the project:

BackgroundTasks10

b. Add new class in it called “BackgroundTasksFactory”:

 public class BackgroundTasksFactory
 {
    public static BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint, string name, IBackgroundTrigger trigger, IBackgroundCondition condition)
     {

       //We will add code here...
     }
 }

 

Before registering new background task you should always check whether it was not registered before.

 public static BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint, string name, IBackgroundTrigger trigger, IBackgroundCondition condition)
 {
    foreach (var cur in BackgroundTaskRegistration.AllTasks)
     {

       if (cur.Value.Name == name)
       // The task is already registered.
       return (BackgroundTaskRegistration)(cur.Value);
     }
 }

 

Once you check it you can register new background task:

 public class BackgroundTasksFactory
 {
    public static BackgroundTaskRegistration RegisterBackgroundTask(string taskEntryPoint, string name, IBackgroundTrigger trigger, IBackgroundCondition condition)
     {
       foreach (var cur in BackgroundTaskRegistration.AllTasks)
       {

          if (cur.Value.Name == name)
          // The task is already registered.
          return (BackgroundTaskRegistration)(cur.Value);

       }

  //Register new background task:
  var builder = new BackgroundTaskBuilder();

  builder.Name = name;
  builder.TaskEntryPoint = taskEntryPoint;
  builder.SetTrigger(trigger);

  if (condition != null)
   {
    builder.AddCondition(condition);
   }

  BackgroundTaskRegistration task = builder.Register();

  return task;
  }
 }

 

c. Register new background task and set the trigger that will start it. You can do it in the “MainPage.xaml.cs” file in the constructor. In our case we will trigger background task when internet connection is retrieved:

 public MainPage()
  {
    this.InitializeComponent();
    BackgroundTasksFactory.RegisterBackgroundTask("BackgroundTasksRuntimeComponent.BackgroundTaskSample", "MyBackgroundTask", new SystemTrigger(SystemTriggerType.InternetAvailable, false), null);
 }

As you can see we have to provide namespace and name of the Background Task (created earlier), give it a name, set trigger (so when our background task should start). Last parameter is optional (can be null) – we can add different conditins to decide when to start task (for instance when user i present).

 

6) Declare your Background Task in the app manifest:

Each Universal Windows 10 App that uses Background Tasks must have it declared in the manifest.

1. Open Package.appxmanifest.

2. Go to “Declarations” section.

3. From the Available Declarations drop-down, select Background Tasks and click Add.

BackgroundTasks11

4. Once you click “Add” you should provie two things:

a. Properties – in this section you should provide the information what kind of operations you perform in the background task. In this case please select “General”:

BackgroundTasks12

b. Entry point: Here you should provide the namespace and class name of your background task:

BackgroundTasks13

 

Type: “BackgroundTasksRuntimeComponent.BackgroundTaskSample”.

 

7) Done! Now we can test our solution:

a. Start application and turn off the Internet. Then turn on it again.

You should see that notification appeared with retrieved JSON data:

BackgroundTasks14

b. Close the app. Then turn off the Internet and turn it on again. You will see that even if your app is closed background task is fired!

BackgroundTasks15

 

Sum up

Now you know how to perform background code in your Universal Windows 10 Apps. It’s really helpful. Try to imagine for instance that once the internet connection is back you would like to sync user data in the background – there is no better way than to use Background Task. Enjoy!

Advertisements