31 Days of Mango | Day #25: Background Agents

Day25-BackgroundAgentsDay24-ProfilerToolDay23-ExecutionModelDay22-AppConnectDay21-Sockets

This article is Day #25 in a series called 31 Days of Mango, and was written by guest author Gary Johnson.  Gary can be reached on Twitter at @GaryGJohnson.

Today we’re going to take a look at one of the multitasking capabilities new to Windows Phone 7.5. The complete multitasking picture is comprised of several new features:

  • Background Agents
  • Background File Transfer
  • Background Audio Playback
  • Scheduled Notifications
  • Fast Application Switching

Here we will focus on Background Agents. While the file transfer and audio playback tasks cover specific scenarios, they do not allow for custom code to be executed. That is where Background Agents come in.

There are two types of Background Agents: Periodic and Resource Intensive. Resource Intensive agents are meant for tasks that will consume a large amount of system resources and come with several limitations for when they can be run. Periodic agents run more frequently and with less restriction, but are meant for tasks that are light on resource consumption. To fully understand the different limitations and benefits of each, refer to the MSDN page.

A periodic task might do something short and simple, such as refresh an RSS feed or update your live tile. A resource intensive task might do something that requires a lot of time and bandwidth, such as syncing or caching large amounts of data from a cloud service.

We are going to make a Periodic Agent that will update your application live tile with the last time the custom task was run.

Getting Started

Launch Visual Studio and create a new project. Under Silverlight for Windows Phone, select Windows Phone Application. Name it “MyAgentApp”.

clip_image002

You’ve now created the main application. It will be responsible for two things:

1) Having a live tile that the Background Agent can update with information

2) Starting and stopping the Background Agent

The Background Agent itself must live in its own special project. Add a new project to your solution, selecting Windows Phone Scheduled Task Agent. Name it MyAgent. This project will contain your custom code that will run in the background and update the live tile.

clip_image004

Finally, and this is important, go to the MyAgentApp project and add a project reference to MyAgent. This will allow you to register your agent from within the application. Also, notice the entry this automatically created in WMAppManifest.xml:

<Tasks>
      <DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
      <ExtendedTask Name="BackgroundTask">
        <BackgroundServiceAgent Specifier="ScheduledTaskAgent" Name="MyAgent" Source="MyAgent" Type="MyAgent.ScheduledAgent" />
      </ExtendedTask>
    </Tasks>
 

Creating the Application

Now it’s time to actually wire everything up. Open MainPage.xaml and add two buttons, one for starting the agent, and the other for stopping the agent:

<StackPanel VerticalAlignment="Center">
        <Button Content="Start Background Agent"
               Click="StartButton_Click"/>
        <Button Content="Stop Background Agent"
               Click="StopButton_Click"/> 
    </StackPanel>
 

 

In MainPage.xaml.cs, wire up the buttons to start and stop the agent:

private const string TASK_NAME = "MyAgent";

private void StartButton_Click(object sender, RoutedEventArgs e)
{
    StartAgent();
}

private void StopButton_Click(object sender, RoutedEventArgs e)
{
    StopAgentIfStarted();
}

private void StartAgent()
{
    StopAgentIfStarted();

    PeriodicTask task = new PeriodicTask(TASK_NAME);
    task.Description = "This is our custom agent for Day 25 – Background Agents";
    ScheduledActionService.Add(task);
#if DEBUG
    // If we’re debugging, attempt to start the task immediately
    ScheduledActionService.LaunchForTest(TASK_NAME, new TimeSpan(0, 0, 1));
#endif
}

private void StopAgentIfStarted()
{
    if (ScheduledActionService.Find(TASK_NAME) != null)
    {
        ScheduledActionService.Remove(TASK_NAME);
    }
}
 

 

Notice that to create our custom agent, we are creating a new PeriodicTask. We then use the name as an identifier when finding and stopping the agent. Notice also that we specified PeriodicTask.Description – this is a required field and will appear in Settings | Background Tasks under the name of our application.

Create the Background Agent

In the MyAgent project, open ScheduledAgent.cs and add the following code:

protected override void OnInvoke(ScheduledTask task)
{
    UpdateAppTile(GetLastUpdatedTimeMessage());
}

private string GetLastUpdatedTimeMessage()
{
    return string.Format("Last Updated: {0}", DateTime.Now);
}

private void UpdateAppTile(string message)
{
    ShellTile appTile = ShellTile.ActiveTiles.First();
    if (appTile != null)
    {
        StandardTileData tileData = new StandardTileData
        {
            BackContent = message
        };

        appTile.Update(tileData);
    }
}
 

ScheduledAgent has one important method to override – OnInvoke. This is where your agent will execute its background task. If your task is complete and you no longer need your agent to run, you can call NotifyComplete() to signal that the task completed successfully or Abort() to signal that you are cancelling your task. To keep the task running at an interval, simply do not call either, which is what we are doing here.

Running the Application

Now that our application is ready to go, deploy it to the device emulator or Windows Phone and run the application. Click the button to start the background agent. Leave the application and find it in your list of applications. Tap and hold on the application and choose “pin to start”. When you view the tile on your start page you should eventually see the application tile flip around, revealing the last time it was updated.

clip_image005

Summary

So, today we created our own custom Background Agent that updates a live tile. When making Background Agents of your own, keep in mind what we covered:

  • Background Agents allow you to execute custom code while your application is not running
  • There are two types of Background Agents – Periodic and Resource Intensive
  • Periodic tasks are for tasks that have low resource consumption, and as a result have fewer restrictions than Resource Intensive tasks
  • Background Agents need their own project, which should be added as a project reference to the application that will start the agent
  • In your agent you need to override OnInvoke()
  • When your task is completed you need to call NotifyComplete() or Abort()

To download a complete Windows Phone project that uses all of the code and concepts from above, click the Download Code button below:

download

Tomorrow we are going to look at another multitasking feature called Background File Transfer that will allow us to download or upload files while our application is not running.  See you then!

toolsbutton

17 thoughts on “31 Days of Mango | Day #25: Background Agents

  1. Pingback: The Morning Brew - Chris Alcock » The Morning Brew #989

  2. Pingback: 31 Tage Mango | Tag #25: Background Agents | leitning.de

  3. Pingback: 31 Days of Mango « Blankenblog

  4. Pingback: WP Astuces » Les 31 jours de Windows Phone Mango sont finis

  5. Pingback: Día 25: Background agents | La Liga Silverlight

  6. Good article. One callout, though. In the code snippet:

    ShellTile appTile = ShellTile.ActiveTiles.First();
    if (appTile != null) . . .

    Shouldn’t that be FirstOrDefault()? I believe using First() there will throw an exception if the collection is empty.

    • First is actually only used for updating the primary Live Tile, which always exists, even when the user hasn’t pinned the app to the Home Screen. For updating any other tile, you’ll want to be certain that the tile exists before you update it.

  7. Pingback: Background Agents Overview for Windows Phone - Scenes From A Developer Memory - Site Root - StudentGuru

  8. Pingback: 31 Days Mango | For things that fit in the pocket

  9. Pingback: Persistent Login Testing Woes Solution – Windows Phone 7 » Jeremiah Isaacson

  10. when i write
    ShellTile appTile = ShellTile.ActiveTiles.First(); in code it shows me error like “Error 1 ‘System.Collections.Generic.IEnumerable’ does not contain a definition for ‘First’ and no extension method ‘First’ accepting a first argument of type ‘System.Collections.Generic.IEnumerable’ could be found (are you missing a using directive or an assembly reference?)

    for that what to do ?

    • getting error ShellTile appTile = ShellTile.ActiveTiles.First(); in this Line . Will you pls help me to solve out it . thanks in advance !!

    • Try adding this to the top of your page:

      using System.Linq;

      That should solve your problem.

  11. You say that ” To keep the task running at an interval, simply do not call either (NotifyComplete, Abort) , which is what we are doing here.” I understand that call either will terminate the agent
    But in the Audio Player Agent sample on MSDN, they call NotifyComplete everytime a PlayState changed, so that the agent is terminated many times, but I see the sample runs well

    Why is that ? Thanks

  12. Pingback: What is System.Windows.ni.dll | Code and Programming

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s