Windows Phone 8 - 6 Background Agents


Published on

Published in: Technology
1 Comment
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Windows Phone Background TasksAt the end of this module, students will be able toDescribe how the Windows Phone OS supports multi-tasking for 3rd party applicationsDescribe the purpose and constraints on periodic and resource intensive background tasksCreate a background agent in Visual StudioWrite applications that use the Background File Transfer ServiceDescribe how to stream audio using the Background Audio Task  
  • Foreground TasksWindows Phone allows only one application to execute at a time. The user can interrupt one application to go and run another, and can long press on the back button to show thumbnails of all current applications and can select one to reactivate (as described in the Fast Application Switching module). However, only one foreground application can display UI, interact with the user and execute at any one time. Windows Phone enforces this behavior to give the user the best possible interaction with the foreground application, and to conserve battery life by not executing a UI application if it is not active.  As we shall see later, this impacts on the way that background tasks work.   
  • Background AgentsWindows Phone allows a foreground application to schedule a background agent to perform processing which the OS will execute even when the main application is not running in the foreground.You can only build one background agent per application, but that agent can operate in one or both of two modes:Periodic Task – a short duration task that the OS may run every 30 minutesResource Intensive Task – runs for longer when the phone is connected to mains power and certain other conditions are metIt is important to realize that the background applications are allowed to run in such a way as to minimise the impact on foreground performance and battery life.You can think of the background agent as being an ‘assistant’ to the main application, a bit like the Lone Ranger and Tonto , or Batman and Robin!    
  • Background Agent Health WarningBackground Agents are a great way of allowing your application to execute code even when the foreground application is not running. Great uses of background agents is to update tiles with new data or show toast alerts, or to update the persistent data of an application from a cloud service so that the data is available the next time the user runs the foreground application.However, you should never put critical logic in a background agent that absolutely must be run as there are a number of ways that they can be disabled:if the phone battery is lowthe system limit for agents has been exceededthe user has disabled the agent for your application through the Settings applicationsThink of them more as a nice bit of sugar icing for your application.Remember that foreground performance and battery life are the driving factors here and as with everything else on the phone, maintaining user satisfaction with the phone is the overriding principle.Note at this point we are not going into any great detail on how this feature works, we are just explaining the development context and fundamentals.I guess the bottom line is that a background agent is actually a piece of icing, rather than cake.   
  • Agents and TasksIt is important to understand the difference, so that the names of the two things make sense. The Task is the scheduling object you use to register your background agent functionality with the OS for later execution in the background, either as a Periodic task or as a Resource intensive tasks.  The Agent is the code that you write and which the Task executes at the appropriate time in the background.  An application can only have one background agent. The same agent can be scheduled to be run in two tasks, one periodic and one resource intensive.When the agent code executes, it can look at the type of the task it is running under, and then behave accordingly (we shall see how to do this later)   
  • PeriodicTask AgentsPeriodicTask agents run every 30 minutes or so and are allowed to continue processing for up to 25 seconds. The phone restricts the total number of background agents that can be registered across all applications, so if that limit has been reached, your code will throw an exception when you try to schedule a new task.Suggested areas where this makes sense include location tracking, polling to see if something has changed (update a data feed, check if something has arrived and so on). The agent can update data, make cloud service calls, update tiles or display toast notifications.Make the point that you are not guaranteed to get run at a particular interval, what you are doing is expressing a preference for this. The OS is responsible for running the agents, you cannot influence this in code or ask for the agent to be run more or less frequently.   
  • ResourceIntensive AgentsThese agents only run when:The phone is connected to the mainsWhen it is not using cellular data, but wifi or desktop USB passthruWhen the Lock Screen is up (so the user is not using the phone)And when the battery charge is at 90% or better In other words, only if the user actually leaves the phone alone long enough, such as when leaving it on charge overnight. ResourceIntensive agents may run for up to 10 minutes and are great for doing data-intensive processing such as downloading and processing large datasets, compressing and decompressing data, or complicated data synchronization with a cloud data service.   
  • Dual-Purpose AgentsYou can only have one Scheduled Task Agent project per application. In that project you write the code to be executed as a PeriodicTask or as a ResourceIntensiveTask.If you want to have both a Periodic and a ResourceIntensive task for your application, you just put the code for the two options into the same ScheduledTaskAgent project, and then at runtime you can determine whether the system is running the Agent as a Periodic task or as a Resource Intensive task, and then you can execute the appropriate logic. We will see later how to tell the difference.   
  • Location TrackerWe should be familiar with the captains log application from the task switching session.If not, just mention that it is a way of storing a sequence of time stamped log items. In this demo, Starfleet Command has asked us to add a location tracking feature to the device, and that this must work even when the log application is running.   
  • Creating a Background AgentYou create a Scheduled Task Agent for an application by adding a new project to the solution and selecting the Scheduled Task project template. You can only have one Scheduled Task project per application.A reminder: “Scheduled Task” doesn’t mean that you can decide when (or if) your background agent gets to run.The scheduling is handled by the OS. 
  • The Captains Log SolutionYou add a scheduled task Agent project to the solution so that it now contains multiple projects. When you compile the solution, each project results in a separate project output (usually an assembly - a dll). When you package up your app into a xap, it will include all the project outputs which are sent to the target device.  
  • Connecting the Agent ProjectThis is very important! In the code that schedules the background agent, which we will look at in a moment, you don’t explicitly reference the class in the Scheduled Task Agent project; you simply schedule a PeriodicTask and/or a ResourceIntensiveTask. The way that the runtime knows which assembly to use to find the background agent code, is through this reference. It is an important linkage between the main program and the agent task.  If you miss this step out things will build OK, but your agents will not run properly.   
  • Background Agent CodeThe project you create using the Scheduled Task Agent project template contains a single class derived from Microsoft.Phone.Scheduler.ScheduledTaskAgent and that contains a single method, OnInvoke.The OnInvoke method is where our background agent does its thing. Note that this is not a situation where the agent does something and then goes to sleep for a while.The agent is externally scheduled and runs to completion each time it is called. If it runs for more than 25 seconds in the case of a Periodic Task, or 10 minutes for a Resource Intensive Task, it will be terminated by the OS task scheduler. When the agent has completed its task, it should call NotifyComplete or Abort to let the operating system know that it has completed. NotifyComplete should be used if the task was successful. If the agent is unable to perform its task – such as a needed server being unavailable - the agent should call Abort, which causes the IsScheduled property to be set to false. The foreground application can check this property when it is running to determine whether Abort was called.  
  • Sharing Data with Background AgentsThis is a very simple example of the code for the agent for the Captain’s Log. It reads data from the exact same Isolated Storage that the foreground application uses. In this example, the first time it runs it might not have a log to read, and so it will start with an empty one and write a different log message back to the log file.The code to load from isolated storage is exactly the same as that used in the foreground application. An agent is bound to a particular application, and can use the isolated storage for that application.The log message string is going to be used in this example to record whether the logfile text was already present in isolated storage or not, so we have a different log message depending on how the initial load went.   
  • Concurrent Data AccessIt is possible for a Periodic Task background agent and the foreground application to be running at the same time.You should guard access to files and other resources in IsolatedStorage to ensure that only one process has access to the files at any one time. A named system Mutex is ideal for this as shown in the code on this slide. The Mutex.WaitOne() method blocks until it can get ownership of the Mutex which it retains until it calls Mutex.ReleaseMutex().Microsoft recommends that you do not use IsolatedStorageSettings to communicate between processes because it is possible for the data to become corrupt. 
  • In this specific example, we need to use the IC_CAP_LOCATION capability.Note that even though the code that requires this is in the background agent project, you must request the capability in the WMAppManifest file of the foreground application.
  • Obtaining the Phone LocationThere might not be time in the 15 seconds or so available for the scheduled task for it to start up a GeoCoordinateWatcher and for that to get a lock and return position information. The GeoCoordinateWatcher is supported for use in background agents, but it uses a cached location value instead of real-time data. The cached location value is updated by the device every 15 minutes. Note that when you test background agents using the emulator, the GeoCoordinateWatcher.Location property does not have position data in it. You do not need to create a PositionChanged event handler to get the position information, which is normally how position information is delivered.   
  • Storing the Phone LocationIn the Captain’s Log sample, the background agent opens the existing LogFile data file from Isolated Storage and appends a new log entry onto it which records the current position of the phone.It then saves the data back to the file in Isolated Storage. The next time you open the foreground application, or record a new log entry using the foreground application, you will see the entries added by the background agent.   
  • Note that the usage shown here is only good for a rough tracking of location every time the agent runs – which will be every 30 minutes or so , as long as the user hasn’t disabled background agents for this app, and the phone hasn’t stopped agent execution because the battery is getting flat.For accurate and continuous background location tracking, we use the new background location tracking capability which is described in the Application Lifecycle and Maps and Location sessions.
  • Showing a NotificationOne of the ways that a background application can communicate with the user is to display a Toast Notification. Toast Notiifcations can be created with an associated URI so that when the user taps on the toast popup, the foreground application launches.  Background Agents can also update Live Tiles. We will look at live tiles in a later module.   
  • Scheduling the Background AgentThis code uses the Find(String) method to obtain a reference to the PeriodicTask with the specified name. If the scheduled task object is not null, then you should call Remove(String) to unregister the agent with the system. You cannot update agents directly. You must remove and then add. When you create a new PeriodicTask object, you assign its name in the constructor. You must also set the Description property as this property is required for Periodic agents and is used to describe the agent to the user in the background tasks Settings page on the device. Call Add(ScheduledAction) to register the Periodic agent with the system. An InvalidOperationException is thrown when Add is called if the user has disabled background agents for the application, so the call should be placed in a try block. If the call throws an exception, verify the message string of the exception. If the string is “BNS Error: The action is disabled”, then you should alert the user that background agents have been disabled.   
  • Debugging a Background TaskIf anyone was wondering how come our “runs every half hour” scheduled agent was running so often, this should help explain it.   
  • For demonstration notes please look in the “Demonstration” folder and open the corresponding Word document.Note – try to demo this on a real phone because of difficulties in getting accurate location fixes from a background agent running on the emulator.
  • What we have just seenThis is a recap of the demo, to make sure we are all agreed on what has just transpired.   
  • Debugging the Agent CodeWhen we exited the foreground application in the demonstration, Visual Studio did not exit debug mode and continued to show the program as running.  Instead it was ready to debug the background task.   
  • For demonstration notes please look in the “Demonstration” folder and open the corresponding Word document.
  • Background Agent TipsReschedule is required every two weeks.Use the ExpirationTime property of the ScheduledTask object to set the time after which the task no longer runs. This value must be set to a time within two weeks of the time when the action is scheduled with the Add(ScheduledAction) method. When the application associated with the task is run in the foreground, it may reschedule the task and reset the expiration time to up two weeks from the current time.Do not implement critical functionality in a Background Agent, as you cannot be sure that the agent will run:The user may disable any agent through the Settings applicationBattery Saver mode is an option that the user can enable on the device to indicate that battery life should be prioritized. If this mode is enabled, periodic agents may not run, even if the interval has elapsed.To help maximize the battery life of the device, there is a hard limit on the number of periodic agents that can be scheduled on the phone. It varies per device configuration and can be as low as 6. There is another limit, which is lower than the hard limit, after which the user is warned that they have multiple background agents running and may, therefore, experience faster battery consumption.Due to the constraints on the device that must be met for resource-intensive agents to run, it is possible that the agent will never be run on a particular device. For example, if a user does not have access to Wi-Fi or a PC, they may never have a non-cellular connection and the resource-intensive agents on their device will never run. Also, resource-intensive agents are run one at a time, so as more applications that use resource-intensive agents are installed on a device, the likelihood of an agent running becomes even less. You should consider this when designing your application. 
  • File Transfer TasksThese are not set up and managed in quite the same way as agents, in that we don’t need a separate project.Instead we just create and manage transfer objects that do the work for us. With Windows Phone OS 7.1 and later, applications are able to queue up one or more file uploads or downloads over HTTP that will be executed in the background, even when the application is no longer running in the foreground. The APIs used for initiating file transfers should be used to query the status existing transfers and provide progress indicators for the end user. The Background Transfer Service only supports transfers using HTTP and HTTPS. FTP is unsupported. You can upload and download files in the background with the BackgroundTransferService. The GET HTTP method is supported for downloading files, and the POST method is supported for downloading or uploading files.   
  • Background Transfer PoliciesMake the point that these policies are in place to protect performance, battery life and the data allowance of our users.  The operating system enforces a number of restrictions on background transfers related to file size, connection speeds, and device resources. This section lists the policies for background transfers for Windows Phone. Note that the Windows Phone Emulator simulates a device that is connected to Wi-Fi and external power. To verify that an application works under other conditions, you should test on a physical device. The background transfer service does not run on non-simultaneous voice and data networks including the following: 2G, EDGE, Standard GPRS The background transfer service does run on networks that are 3G and higher. 
  • The BackgroundTransfer NamespaceMake the point that there is no need to include any additional libraries for this feature. The background transfer service APIs can be found in the Microsoft.Phone.BackgroundTransfer namespace. The primary programming elements you will use are the BackgroundTransferRequest and the BackgroundTransferService classes. The BackgroundTransferRequest object represents a single transfer request including the target and destination file paths, the transfer method, and the current status of a transfer. The BackgroundTransferService object is used to initiate new transfers and to query for or remove existing file transfers.   
  •  Creating a Background TransferThis creates the request and sets it up. It takes the server URL string held in the transferFileName variable and creates a URI object from it. If the URL string has not already been escaped, you should do so using EscapeUriString. Pass this URI to the constructor for BackgroundTransferRequest.  Next, set the transfer method. This example uses GET, but POST is also supported. Note that we have not started the request running yet. 
  • Setting the Transfer DestinationThis part of the code builds the uri for the destination in isolated storage where the downloaded file is to be stored.The first line just chops the filename off the source file name path and then builds a path in isolated storage. All local paths for background transfers must be within the isolated storage for your application within a root directory named “/shared/transfers”. This directory is created by the operating system upon application installation, but if your application deletes or renames this directory, you must re-create it before initiating any file transfers.  You can create any additional directory structure you choose underneath the root “/shared/transfers” directory, and you can copy or move files after the transfer is complete to ensure that the background transfer service does not modify the files, but attempting to initiate a transfer using a path outside of the “/shared/transfers” directory will throw an exception. This code also sets the TransferPreferences for the request. This property allows applications to request that background transfers proceed when only a cellular connection is available and when the device is on battery power. This is only a preference setting. It does not guarantee that transfers will take place under these conditions. The default value is None, which indicates that transfers should occur only when a Wi-Fi connection is available and when the device is connected to external power.
  • Starting the TransferMake the point that Add can fail. It will throw an InvalidOperationException if one of the built-in limits has been exceeded If transfers are not explicitly removed when they are complete they will stay around and block further transfers. We will address this later.The following limits apply to BackgroundTransferRequest:Maximum outstanding requests in the queue per application (this includes active and pending requests).25 – Transfers are not removed from the queue automatically when they complete. Applications should use Remove(BackgroundTransferRequest) to remove completed transfers from the queue to keep the slots free for new transfers.Maximum concurrent transfers across all applications on the device2Maximum queued transfers across all applications on the device500Maximum number of HTTP headers per request15Maximum size of HTTP headers16 KB each
  • Monitoring the TransferThese events are fired for us by the transfer. We can update a progress bar or ticker, or we can do something with the transferred resource when it has arrived. Background transfers initiated with the Background Transfer APIs will typically begin as soon as the requirements set by the TransferPreferences property as well as system requirements related to battery power and available connections are met. However, because multiple applications may have background transfers queued up, there may be an additional delay before transfers begin while previously added transfers complete. If the initiating application is still the foreground application, these events will fire to allow you to monitor progress. If your application is not running, you will have to execute code to find the BackgroundTransferRequest object and check the completion status the next time the user runs the application.   
  • Transfer Progress ChangedThis is the simple event handler method. Note that the code uses the BytesReceived property of the transfer request to monitor progress. The actual request the event refers to is provided as a parameter to the event.     
  • Transfer Status ChangedThis is the simple event handler method used to check completion status of the transfer. When a transfer completes: The TransferStatus property will have the value Completed. Determine whether the transfer was successful by checking the StatusCode property which contains the HTTP status code returned from the target server. The value will be 200 or 206 if the transfer was successful, depending on the server configuration. We recommend that you check for both. Any other status codes indicate a server error. How you handle server errors depends on your application. Check the TransferError property to help determine why a failed transfer was unsuccessful. If a file download is successful, you may want to move the file from the “/shared/transfers” directory to a new location in isolated storage so that it is not exposed to future background transfer operations.    
  • Removing a TransferYou might assume that completed transfers would be automatically removed from the request queue. The system does not automatically remove completed transfers. If you fail to remove old transfers and exceed the application limit, an exception will be thrown when you attempt to add new transfers. Remove the transfer request from the queue by calling the Remove(BackgroundTransferRequest) method of the BackgroundTransferService.  Applications are limited to five simultaneous transfer requests, including pending, active, and completed requests.     
  • For demonstration notes please look in the “Demonstration” folder and open the corresponding Word document.
  • Transfer ManagementAfter your application launches, it should:Iterate through all of the background transfers for your application by using the Requests property of the BackgroundTransferService object.For each request, register a handler for the TransferStatusChanged event so that your application can respond to changes in state that occur while the application is running.For each request, register a handler for the TransferProgressChanged event. This is useful for informing the user about the progress of active transfers. For each request, examine the TransferStatus property to determine whether any transfers have completed or changed state while the application was inactive.Use the aforementioned callbacks to update the application UI instead of using a timer or some other mechanism to poll the service for changes.The MSDN example application at the URL shown walks through the steps your application should take.   
  • Getting active transfersWhenever your code refreshes the list of current transfer requests, make sure that you dispose of any existing references first. The BackgroundTransferRequests.Requests property returns a list of objects that are new references to TransferRequests objects, so you must dispose of any existing references you hold first. An application can then iterate through the list, check the status of transfers and bind event handlers as required. Remind everyone that the transfer requests will hang around until they are explicitly removed.     
  • Securing transfersYou can use SSL server certificates to encrypt the communications channel between the service and and Background File Transfer service on the phone.You can also support HTTP Basic Authentication by manually encoding the username and password and inserting the Authorization HTTP header as shown. Note that since the username and password are communicated in clear text, you must use SSL to encrypt these communications otherwise your credentials are exposed to anyone who is snooping on your network traffic.
  • Audio Playback AgentsThis course does not cover Audio playback Agents in details. Make the point that the fundamentals are the same for this technology, although the new project template application is much more fully worked. Starting with Windows Phone OS 7.1, you can write applications that play audio in the background. This means that even after the user has left your application by pressing the Back button or the Start button, your application can continue to play audio. There are two types of background audio applications. One type implements a simple playlist and passes a URI containing the address of a media file to the Zune Media Queue to set the current track. The URI can be local to the phone or a remote address. In either case, the audio needs to be of a type supported by Windows Phone for playback. The other type of background audio application uses MediaStreamSource to implement an audio stream to feed audio samples to the playback system. The format of this stream can be anything you want because you implement a class derived from MediaStreamSource to handle the streaming and decoding of audio. There is a very comprehensive example on MSDN.   
  • ReviewThe important point to make is that a background process is not the same as a process running in the background.  They are tailored for specific tasks and have constrained abilities and runtime environments. They are as easy to debug as any other application.   
  • Windows Phone 8 - 6 Background Agents

    1. 1. Oliver Scheer Senior Technical Evangelist Microsoft Deutschland Background Agents New updates from Background Agent
    2. 2. Topics • Windows Phone task management • Multi-tasking with background agents • Creating tasks in Visual Studio • File transfer tasks • Background notifications • Background music playback tasks
    3. 3. Foreground Tasks • Normally a Windows Phone application runs in the “foreground” • Has access to screen and interacts directly with the user of the phone • At any given time one application is running in the foreground • Although others may be in the memory of the phone and can be selected as required • This is to ensure the best possible performance and battery life for the phone user 3
    4. 4. Background Agents • A Windows Phone application can start a “background agent” to work for it • It is a PeriodicTask, ResourceIntensiveTask or both at the same time • There is only one agent allowed per application • The agent can run when the main application is not in the foreground • An agent is not equivalent to a foreground application running in the background • It is limited in what it can do and the access it has to the processor and other phone facilities 4
    5. 5. Background Agent Health Warning • The number of agents allowed to be active at one time is restricted by the Windows Phone operating system • If the right conditions do not arise for an agent it will not be started • Background agents only run in situations where the operating system feels able to give them access to the processor • If the phone goes into “Power Saver” mode it may stop running background agents completely • Users can also manage the agents running on their phone and may chose to disable them 5
    6. 6. Agents and Tasks • A Task is the scheduling type you request when you schedule a background agent to run • It is managed by the operating system which runs the agent at the appointed time • There are two kinds of Tasks • Periodic tasks that are run every now and then • Resource intensive tasks that run when the phone is in a position to let them • The background Agent is the actual code functionality you write which runs in the background and which does the work • The agent code is implemented in a class that derives from BackgroundAgent • The class is created as part of a Scheduled Task Agent Project 6
    7. 7. PeriodicTask Agents • A PeriodicTask Agent runs every now and then • Typically every 30 minutes or so, depending on loading on the phone • It is intended to perform a task that should be performed regularly and complete quickly • The agent is allowed to run for 25 seconds or so • Memory usage allowed<= 6 MB • Unscheduled after two consecutive crashes • The phone sets a limit on the maximum number of active agents at any time • Good for location tracking, polling background services, tile updates 7
    8. 8. ResourceIntensive Agents • Resource Intensive Agents run when the phone is in a position where it can usefully perform some data processing: • When the phone is powered by the mains • When the battery is >90% charged • When the phone is connected to WiFi • When the phone is not being used (Lock screen displayed) • A “resource intensive” agent can run for up to 10 minutes • Memory usage allowed<= 6 MB • Unscheduled after two consecutive crashes • Good for synchronisation with a host service, unpacking/preparing resources, compressing databases 8
    9. 9. Dual purpose Agents • It is possible for an application to perform both periodic and resource intensive work in the background • This can be achieved using a single background agent class, run from both kinds of task • The agent will run periodically and when the phone is in a position to allow resource intensive work • When the agent starts it can determine the context in which it is running and then behave appropriately 9
    10. 10.            Background Agent Functionality
    11. 11. Location Tracker • The Location Tracker program is a simple logging application • It tracks the location of the phone by using a background agent to regularly store the location of the phone in a text log file • The agent will update the position even when the log program is not active 11
    12. 12. Creating a Background Agent • A background agent is added to the application solution as a “Scheduled Task” • There is a Visual Studio template just for this • This agent will contain the code that runs when the agent is active 12
    13. 13. The Captains Log Solution File • The solution file contains two projects • LocationLogger: the Windows Phone project which is the main application • LocationLogTaskAgent: the background agent to perform the tracking • Solutions can contain many types of different projects • When the solution is built all the assembly file outputs will be combined and sent to the phone 13
    14. 14. Connecting the Agent Project • The CaptainsLog project contains a reference to the output of the LocationTaskAgent project • The foreground application does not directly reference any objects in the agent class in code • Nonetheless, we have to explicitly link these two projects by adding a reference to the LocationTaskAgent output to the CaptainsLog project 14
    15. 15. Background Agent Code • We must implement the agent functionality in the OnInvoke method • It notifies the run time system when it has completed namespace LocationLogTaskAgent { public class ScheduledAgent : ScheduledTaskAgent { protected override void OnInvoke(ScheduledTask task) { //TODO: Add code to perform your task in background NotifyComplete(); } } }
    16. 16. Sharing Data with Background Agents protected override void OnInvoke(ScheduledTask task) { string message =""; string logString = ""; if (LoadLogFromIsolatedStorageFile() { message = "Loaded"; } else { message = "Initialised"; } ... }
    17. 17. Concurrent Data Access 17 • Protect access to files in Isolated Storage by using a named Mutex • Make sure you release the mutex public bool LoadLogFromIsolatedStorageFile() { mut.WaitOne(); // Wait until it is safe to enter try { // read the file here return true; } catch { LogText = ""; return false; } finally { mut.ReleaseMutex(); // Release the Mutex. } }
    18. 18. Selecting the Location capability • In Windows Phone 8 a new application does not have all its capabilities enabled when it is created • The WMAppManifest.xml file in the Properties folder must be opened and the location tracking capability selected • Otherwise the program will fail to run • Don’t forget to specify capabilities in your foreground app project that your background agent needs 3/18/201418
    19. 19. Obtaining the Phone Location 19 protected override void OnInvoke(ScheduledTask task) { ... GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(); watcher.Start(); string positionString = watcher.Position.Location.ToString() + System.Environment.NewLine; ... }
    20. 20. Storing the Phone Location 20 • The background agent now constructs a location message, with a timestamp and then saves the log string back to isolated storage • This string can be displayed for the user by the foreground application protected override void OnInvoke(ScheduledTask task) { ... logString = logString + timeStampString + " " + positionString; SaveLogToIsolatedStorageFile (); ... }
    21. 21. • The code shown in this sample gets a new location whenever the Periodic agent runs • Every 30 minutes or so • Windows Phone 8 supports continuous background location tracking • Suitable for Run Tracking apps and Turn-by-Turn navigation • This is not covered here! • See the Location and Maps module Background Location Tracking 3/18/201421
    22. 22. Showing a Notification 22 • The background task can pop up a toast notification to deliver a message • If the user taps the message it will start up the foreground application • Toast messages will not appear if the foreground application is active protected override void OnInvoke(ScheduledTask task) { ... ShellToast toast = new ShellToast(); toast.Title = "Location Log"; toast.Content = message; toast.Show(); ... }
    23. 23. Scheduling the Background Agent 23 PeriodicTask t; t = ScheduledActionService.Find(taskName) as PeriodicTask; bool found = (t != null); if (!found) { t = new PeriodicTask(taskName); } t.Description = description; t.ExpirationTime = DateTime.Now.AddDays(10); if (!found) { ScheduledActionService.Add(t); } else { ScheduledActionService.Remove(taskName); ScheduledActionService.Add(t); }
    24. 24. Debugging a Background Task • It would be annoying if we had to wait 30 minutes to get code in the agent running so we could debug it • When we are debugging we can force the service to launch the agent • Such code can be conditionally compiled and excluded from the release build 24 #if DEBUG_AGENT ScheduledActionService.LaunchForTest(taskName, TimeSpan.FromSeconds(60)); #endif
    25. 25. What we Have Just Seen • The Location Logging application fired off a background task • The task began running even if the Location Log application is still running in the foreground • The background task loaded location information from the phone and added it to the log file that could then be displayed later • The background task displayed popup notifications each time that it ran 26
    26. 26. Debugging the Agent Code • When you use the Back button or Start on the phone to interrupt an application with an active Background Task, Visual Studio does not stop running • It remains attached to the application • You can then put breakpoints into the background task application and debug them as you would any other program • You can single step, view the contents of variables and even change them using the Immediate Window • This is also true if you are working on a device rather than the emulator • The same techniques work on ResourceIntensive agents 27
    27. 27. Background Agent Tips • Renew often • You must reschedule agents from your foreground app at least every two weeks • Do not implement critical functionality in a background agent • User can disable them • OS can suspend them in low battery situation • If you need more reliable execution of code outside your application and need to update Tiles or send Toast notifications, consider Push Notifications
    28. 28. Background File Transfers
    29. 29. File Transfer Tasks • It is also possible to create a background task to transfer files to and from your application’s isolated storage • The transfers will take place when the application is not running • An application can monitor the state of the downloads and display their status • Files can be fetched from HTTP or HTTPS hosts • At the moment FTP is not supported • The system maintains a queue of active transfers and services each one in turn • Applications can query the state of active transfers 31
    30. 30. Background Transfer Policies • There are a set of policies that control transfer behaviour • Maximum Upload file size: 5Mb • Maximum Download file size over cellular (mobile phone) data: 20Mb • Maximum Download file size over WiFi: 100Mb • These can be modified by setting the value of TransferPreferences on a particular transfer • Maximum number of Background Transfer Requests per app: 25 • Increased from 5 in Windows Phone OS 7.1 32
    31. 31. The BackgroundTransfer namespace • The Background Transfer services are all provided from the BackgroundTransfer namespace • You do not need to create any additional projects to create and manage background transfers 33 using Microsoft.Phone.BackgroundTransfer;
    32. 32. Creating a Background Transfer 34 • This creates a request and sets the source for the transfer • It also sets the transfer method • POST can be used to send files to the server Uri transferUri = new Uri(Uri.EscapeUriString(transferFileName), UriKind.RelativeOrAbsolute); // Create the new transfer request, passing in the URI of the file to // be transferred. transferRequest = new BackgroundTransferRequest(transferUri); // Set the transfer method. GET and POST are supported. transferRequest.Method = "GET";
    33. 33. Setting the Transfer Destination 35 • Files are transferred into isolated storage for an application • This code also sets the preferences for the transfer • TransferPreferences has a number of different settings string downloadFile = transferFileName.Substring( transferFileName.LastIndexOf("/") + 1); // Build the URI downloadUri = new Uri("shared/transfers/" + downloadFile, UriKind.RelativeOrAbsolute); transferRequest.DownloadLocation = downloadUri; // Set transfer options transferRequest.TransferPreferences = TransferPreferences.AllowCellularAndBattery;
    34. 34. try { BackgroundTransferService.Add(transferRequest); } catch (InvalidOperationException ex) { MessageBox.Show("Unable to add background transfer request. " + ex.Message); } catch (Exception) { MessageBox.Show("Unable to add background transfer request."); } Starting the Transfer 36 • This adds a transfer request to the list of active transfers • An application can have a maximum of 25 transfers active at one time • The Add method will throw exceptions if it fails
    35. 35. Monitoring the Transfer 37 • The application can subscribe to events fired by a TransferRequest • TransferProcessChanged is used for progress bars • TransferStatusChanged is used when the transfer completes or fails // Bind event handlers to the progess and status changed events transferRequest.TransferProgressChanged += new EventHandler<BackgroundTransferEventArgs>( request_TransferProgressChanged); transferRequest.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>( request_TransferStatusChanged);
    36. 36. Transfer Progress Changed 38 • When the progress changes our application can update a progress display • You could use a progress bar here void request_TransferProgressChanged(object sender, BackgroundTransferEventArgs e) { statusTextBlock.Text = e.Request.BytesReceived + " received."; }
    37. 37. void request_TransferStatusChanged(object sender, BackgroundTransferEventArgs e) { switch (e.Request.TransferStatus) { case TransferStatus.Completed: // If the status code of a completed transfer is 200 or 206, the // transfer was successful if (transferRequest.StatusCode == 200 || transferRequest.StatusCode == 206) { // File has arrived OK – use it in the program } ... Transfer Status Changed 39 • This code checks that the file has arrived OK
    38. 38. Removing a Transfer 40 • When a transfer has completed it is not automatically removed by the system • This can cause completed transfers to block any new ones • It is important that completed transfers are removed • Note that the remove process may throw an exception if it fails try { BackgroundTransferService.Remove(transferRequest); } catch { }
    39. 39. Transfer Management • An application can find out how many file transfers it has active • It will have to do this when it is restarted, as file transfers will continue even when the application is not running • It can then perform transfer management as required • There is a good example of transfer list management on MSDN
    40. 40. Getting Active Transfers IEnumerable<BackgroundTransferRequest> transferRequests; ... private void UpdateRequestsList() { // The Requests property returns new references, so make sure that // you dispose of the old references to avoid memory leaks. if (transferRequests != null) { foreach (var request in transferRequests) { request.Dispose(); } } transferRequests = BackgroundTransferService.Requests; }
    41. 41. Supplying Credentials for Transfers string username = "user"; string password = "pass@word1"; Uri transferUri = new Uri(""); BackgroundTransferRequest myReq = new BackgroundTransferRequest(transferUri); myReq.Method = "GET"; string usernamePassword = username + ":" + password; myReq.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(StringToAscii(usernamePassword))); string downloadFile = "test"; Uri downloadUri = new Uri("shared/transfers/test", UriKind.RelativeOrAbsolute); myReq.DownloadLocation = downloadUri; BackgroundTransferService.Add(myReq);
    42. 42. Background Audio
    43. 43. Audio Playback Agents • Also possible to create an Audio Playback Agent that will manage an application controlled playlist • The mechanism is the same as for other background tasks • The audio can be streamed or held in the application isolated storage 46
    44. 44. Review • An application can create background processes • Periodic Task tasks run every 30 minutes or so as scheduled by the OS • ResourceIntensive tasks run when the device is connected to mains power, the battery is charged to 90% or better and the phone is not in use • Audio Playback run alongside the application • Applications and their background processes can communicate via the local folder which is common to both • Visual Studio can be used to debug background tasks in the same way as foreground applications • The Background File Transfer service may be used to schedule file transfers with the OS 47
    45. 45. The information herein is for informational purposes only an represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. © 2012 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.