Day: December 29, 2011

EvenTiles from Start to Finish–Part 11

In the previous episode of this series about how to develop a Windows Phone application from scratch we started talking about using a PeriodicTask to perform background processing for our application. You learned how to create a Windows Phone Scheduled Task Agent, a separate project that became part of the EvenTiles solution to host a PeriodicTask. You also learned how the PeriodicTask relates to the EvenTiles to enable background processing for the application. In this episode of EvenTiles we will take a look at how to debug the PeriodicTask.

When you have added a PeriodicTask to your application you may have noticed that the behavior of Visual Studio’s debugger did change. Instead of detaching the debugger if you terminate the application, the debugger remains attached. This allows you to debug the PeriodicTask when the application is no longer executing. This is of course important because typically the PeriodicTask executes without our application being active. Under normal circumstances, a PeriodicTask will run once every 30 minutes for a few seconds. This schedule can not be changed for released applications and is determined by the operating system. Of course debugging a PeriodicTask would be unproductive in this way. Therefore there is a possibility to run your PeriodicTask more frequent under test.

If you take a look at the ScheduledActionService class, you will see that it contains a static method called LaunchForTest. This method allows you to schedule a Periodic Task to run at the time you specify. Since you will only use this method for testing Periodic Tasks, draining the battery by frequently executing code in the background is not really an issue. However, you will must not forget to remove the call to LaunchForTest in your production code. You can for instance do this by making use of conditional compilation. What I like to do is to define a separate symbol (to be used in combination with DEBUG) to control execution of LaunchForTest. Usually in Debug mode you want to test your Periodic Task frequently, but by defining a separate symbol, you can also easily disable calling LaunchForTest, even in Debug mode. The following code fragment defines the DEBUG_TASK constant:

Conditionally defined constant
  1. #if DEBUG
  2. #define DEBUG_TASK
  3. #endif

Since this constant is not defined in Release mode, you don’t have to worry about accidentally adding a call to LaunchForTest in your released application. If you want to test your Periodic Agent with a normal schedule in Debug mode, you can simply change the name of the constant, for instance into NDEBUG_TASK. To make sure that the Periodic Agent will be called more frequent then usual, you can make use of the following code (inside the #if and #endif directives):

Calling Periodic Agent faster
  1. private void StartPeriodicAgent()
  2. {
  3.     RemovePeriodicAgent();
  4.  
  5.     evenTilesPeriodicTask = new PeriodicTask(evenTilesPeriodicTaskName);
  6.     evenTilesPeriodicTask.Description = "EvenTilesPeriodicTask";
  7.  
  8.     try
  9.     {
  10.         ScheduledActionService.Add(evenTilesPeriodicTask);
  11. #if DEBUG_TASK
  12.         ScheduledActionService.LaunchForTest(evenTilesPeriodicTaskName, TimeSpan.FromSeconds(30));
  13. #endif
  14.     }
  15.     catch (InvalidOperationException ex)
  16.     {
  17.         if (ex.Message.Contains("BNS Error: The action is disabled"))
  18.         {
  19.             MessageBox.Show("Background agents for this application are disabled.");
  20.         }
  21.     }
  22. }

As a result, the Periodic Task will now be executed approximately 30 seconds after this statement is executed. After that, the Periodic Task will execute on its normal 30 minute schedule, unless you add the call to LaunchForTest in the DoInvoke method of the Periodic Task as well:

Relaunching Periodic Agent
  1. protected override void OnInvoke(ScheduledTask task)
  2. {
  3.     //TODO: Add code to perform your task in background
  4.  
  5. #if DEBUG_TASK
  6.     ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(30));
  7. #endif
  8.  
  9.     NotifyComplete();
  10. }

The following video shows you how to use the LaunchForTest method inside the EvenTiles application and how to make use of the Visual Studio debugger to test the Periodic Agent:

Debugging a Windows Phone Application’s PeriodicTask using LaunchForTest.

Of course the functionality of the Periodic Agent is still to be determined. In part 12 of EvenTiles we will work on adding functionality for the Periodic Agent.