So far, this series has talked about all kinds of problems you may run into with background agents, like API restrictions, timeout/memory constraints, data exchange between your app and your agent and finally possible error conditions when you want to create tasks. There's one additional topic I want to talk about briefly, because it's a really important one, and it took me a while to figure out the exact inner workings of it myself.
Part 5: Expiration Time
When I started working with background agents, there were only a few vague hints available for a particular behavior of the operating system regarding their expiration. It wasn't clear to me what exactly happens and what an app is responsible for (or allowed to do) with regards to this, so I went through some painful experience to learn the details (for example, an update for the SilverlightShow app to fix an issue with this was needed). Luckily, the documentation on MSDN on this is much better today, and together with my following explanation hopefully you won't have to go through the same process like me.
Understanding the concept
The idea behind the concept of having an expiration time for your agents is that sometimes people will lose interest in your app and stop using it, but they might not necessarily remember turning off a configured background agent either through your app or the device settings. The result would be that although it is not used anymore, the app would still continue to drain device resources like battery and potentially also permanently use network bandwidth and traffic. To solve this problem, a decision has been made to let agents expire automatically after a certain amount of time.
To prevent your agent from expiration, it needs to be renewed regularly. The important thing is that this is not performed automatically by the operating system, for example when the user runs your app; as stated in the documentation of the Background Agents Overview, and even more clearly in that of the ExpirationTime property of the ScheduledTask class, it's your app's responsibility to do that manually when it is in the foreground.
How it is done
There's no particular way to renew an agent. Instead, you simply remove it from the list of scheduled tasks, and then add a new one back in, with a newly set expiration time. The default value for that property is 14 days in the future from the current date, which also is the maximum value that is allowed. So if you want to make use of the latest possible expiration date, you don't need to set this property explicitly. A sample implementation of this could look like:
// find and remove the task
var task = ScheduledActionService.Find(agentName) as PeriodicTask;
if (task != null)
// add a new one
// (no need to set the ExpirationDate property explicitly)
var task = new PeriodicTask(agentName);
task.Description = description;
Note: Do not forget that adding a task can result in certain exceptions to be thrown, and add proper error handling.
One pattern to use this code is at application startup. You can check whether the conditions for running your background agent still apply, and then run that code to apply the new expiration date.
What happens if you do not renew the task regularly? Your task then is removed from the list of scheduled tasks by the operating system automatically after the expiration date has passed. There's a separate area in the device settings that allow you to manipulate the current background tasks; when your task was deactivated it will be listed as "off" here:
The slightly irritating thing is that the detail page for that task allows you to set the following option:
Although this sounds like it, there's no auto-magic happening here to turn that task back on. If your app does not have any manual logic to renew the task, nothing will happen even if this option is checked. On the other hand, if the option is not checked here, your app will not be able to re-activate the task, even if it tries to. An exception will be thrown, as I described in part 4 of this series.
One final thing to take from all this is that if the user does not use your app in (at most) 14 days, any existing background agent for it will be disabled, and there's nothing you can do about that.