Background tasks, depending on the conditions which trigger them, can run when their associated app is also running. The question then arises: how can the background task communicate with the app?

As noted in yesterday’s post, a background task can write to the app’s appdata areas, which is the way for the background task to pass information to the app. The app, for that matter, can also store information there for a background task to find when it’s next run.

When the background task writes data, the question then becomes how the background task can tell the app that there’s new data available.

There are two ways to do this. First is the completed event that’s part of the BackgroundTaskRegistration class. The app gets an instance of this class back from BackgroundTaskBuilder.register when it sets up a background task, after which it can then assign a handler for completed. This works well, then, for a background task that does some work that the app wants to pick up when the task is completely finished. Because the app knows which background task was associated with that particular handler, it knows where to look for the appropriate appdata.

The Background task sample in the Windows SDK uses completed handlers all over the place to give visual output when a task is complete (and also as it supports progress). In the JavaScript version of the sample, the handler is found at the end of the js/global.js file. The attachProgressAndCompletedHandlers function earlier in that file is where the handlers are assigned, and this function is called from the earlier registerBackgroundTask that call the WinRT APIs.

The second means of communication works at any time during execution of the background task, which is calling Windows.Storage.ApplicationData.signalDataChanged. This will raise a Windows.Storage.ApplicationData.datachanged event in the app (assuming it’s listening), as is also raised when Windows roams new app data from the cloud. The trick here is that the event doesn’t receive any indication of what data, exactly, was changed, so it needs to go examine any data that it expects might have changed.

Clearly, though, if an app only has one or a small number of background tasks that write to local appdata, then there’s not much to go inspect (it’s less likely that a background task would write to roaming appdata, though that’s not out of the question). So it’s workable–it just takes a little more work!

To see this in action, take the aforementioned sample, and navigate to the Tasks project (a C# project) and open SampleBackgroundTask.cs. Within PeriodicTimerCallback, add the following after the line that starts with settings.Values[key] == …:

Windows.Storage.ApplicationData.Current.SignalDataChanged();

The in the main project of the sample (again using the JavaScript variant), open js/sample-background-task-with-condition.js and add the following at the end of the ready method near the top (after the line that reads SampleBackgroundTaskWithCondition.updateUI();)

Windows.Storage.ApplicationData.current.ondatachanged = function (appdata) {
    console.log(“Appdata changed.”);
}

Set a breakpoint on console.log, then run the app and go to scenario 3. Click the Register button which will execute the ondatachanged assignment above. Then pull down the Suspend menu where you can trigger the SampleBackgroundTaskWithCondition:

background task selection

After the task does it’s work (you’ll see progress reported), it will call SignalDataChanged which should hit your breakpoint.

 


One Comment

  1. philk
    Posted May 1, 2013 at 8:10 pm | Permalink

    When I read the Background Task API docs I always wonder why the whole registration stuff is required for the programmer to code instead of heaving it declared entirely in the app manifest. I am currently writing my own XML that describes background tasks of an app and performs all the code required to wire it up with the system.

2 Trackbacks

  1. [...] Using the background task completed event and signalDataChanged to communicate with the app (Kraig Brockschmidt) [...]

  2. [...] Using the background task completed event and signalDataChanged to communicate with the app (Kraig Brockschmidt) [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>