From a background task, it's perfectly allowable to issue a tile update, for instance, when procedding a raw push notification in that task and updating a tile in response. With secondary tiles, you might also want to update the tile's arguments so that it launches into different content relevant to the tile update. However, secondary tile arguments are statically defined when the tile is pinned and cannot be changed later.

To work around this, you can use a set of static identifiers that you then dynamically map to your variable data. It's simplest to just keep a table of secondary tile IDs mapped to their dynamic arguments, in which case you're probably not using the static arguments at all.

Another question with background tasks is whether it's possible to do file I/O therein, because clearly if you're modifying a table of secondary tile arguments in a file you'll be doing file I/O. The thing to remember here is that if you use any kind of async APIs in the process, you need to make sure the background task stays active until the async work is complete. To do this, you use the deferral mechanism.

In C#, the general pattern is like this:

public async void Run(IBackgroundTaskInstance taskInstance)
{
    var deferral = taskInstance.GetDeferral();
    var contents = await DoAsyncWork();
    deferral.Complete();
}

In JavaScript, the deferral is found on the WebUIBackgroundTaskRuntimeClass object. You retrieve this in the worker with Windows.UI.WebUI.WebUIBackgroundTaskInstance.current, then call its getDeferral method, do your async work, and then call the deferral's completed method when you're done.

var task = Windows.UI.WebUI.WebUIBackgroundTaskInstance.current;
ver deferral = task.getDeferral();

DoWorkAsync().done(function () {
    deferral.completed();
    close();  //Shut down the background task
});

Note that JavaScript it's also necessary to call close() when the task is finished (which is WorkerGlobalScope.close()).

 


As I’ve had occasion to look at more C#/XAML code lately, I’ve noticed a common pattern around the await keyword. Make no mistake: await is a marvelous language construct that makes it super-simple to write code using async APIs that otherwise looks like synchronous code:

private async Task<[type]> MyFunction()
{
String result1 = await Operation1();
String result2 = await Operation2(result1);
processResults(result2);
await Operation3();
return [something];
}

Once EcmaScript6 is adopted in the app host for Windows Store apps written in JavaScript, we’ll see the same thing in that language as well.

What’s important to remember about await, however, is that it’s not always necessary. That is, if you simply need to start an async operation but don’t need its results right away, then you don’t need to stick an await in front of it and block the current thread. That is, you don’t want to force synchronous behavior where it’s not actually necessary, allowing instead for some operations to run in parallel.

In the code snippet above, for instance, we clearly need to wait for Operation1 to finish before invoking Operation2 because we need result1 as input to Operation2. Operation3, however, is not dependent on Operation2 at all, so it can clearly be running while we wait for Operation2 to finish.

In addition, because we’re not returning anything from Operation3, we don’t need to await that one before returning from the function.

Remember that await is just an easy way to avoid writing explicit async structures with an explicit completed handler (as you have to do in JavaScript today), and if you don’t need to do anything with those results, then it’s not necessary to use await at all. (For more background on async and await, see Diving deep with WinRT and await on the Win8 Developer Blog.)

The code above, then could be written as follows to allow Operation2 and Operation3 to run in parallel, along with anything that happens after MyFunction returns:

private async Task<[type]> MyFunction()
{
String result1 = await Operation1();

String asyncOp = Operation2(result1);
asyncOp.Completed = delegate(IAsyncOperation<String> result2, AsyncStatus status)
{
if (status == AsyncStatus.completed)
{
processResults(result2)
}
};

Operation3();
return [something];
}

It’s more code to write, but will generally make for better performance in your app.

 

 


One of the interesting things about working with async APIs is that, well, they’re asynchronous. You never quite know when they’ll start nor when they’ll complete. When working in JavaScript, also not always obvious how to stop an operation once it gets going. In other languages, where you have direct access to the IAsyncOperation and related interfaces that derive from IAsyncInfo, it’s quite clear that you can call IAsyncInfo.Cancel to do the job.

Async operations are projected into JavaScript as promises, and it’s there that you have to look. Simply, the promise object has a cancel method, which will internally invoke the IAsyncInfo method.

I saw a forum post today asking how to tell which page in an JavaScript app started an async operation, as the operation could complete after the app has navigated to a new page. It’s really not the right question, because if a page starts any async operations that are that page-specific (that is, would only be processed by that page alone), then you should cancel the promises for each operation in the page’s unload method. If the operation isn’t page-specific, then it doesn’t belong inside a page control in the first place.


It occasionally comes up that you need to serially iterate over a synchronous collection, but doing so involves async APIs. For example, you have a vector of StorageFile objects and want to call copyAsync on each of them, one at a time, in the order of the vector.

This can be accomplished with the following code (thanks to Adam Comella for this solution). Assuming that storageItems is the list over which you want to iterate and destination is the folder into which you want to copy those items, you can do this:

var storageItemsPromise = WinJS.Promise.as();
storageItems.forEach(function (item) {
     storageItemsPromise = storageItemsPromise.then(function () {
         return item.CopyAsync(destination);
     });
});
// Call done so that if CopyAsync throws an exception, it’ll cause the app to terminate
storageItemsPromise.done();