November 2011 - Posts - Jon Galloway

November 2011 - Posts

Leveraging Background Services and Agents in Windows Phone 7 (Mango)

Earlier this month at DevConnections, I gave a presentation on Background Services and Agents in Windows Phone 7. The next week, I got to join Jesse Liberty on his podcast interviewing Peter Torr, a Prinicpal Product Manager on the Windows Phone team who's written a lot of great content about this exact subject.

Overall, I was very impressed. I've done some basic Windows Phone development in the past, but nothing that really cutting edge. I really liked the way Windows Phone balanced enabling features for developers with protecting the phone's resources.

Side note: why you, Jon?

If you follow my blog, you might wonder what I was doing speaking on Windows Phone, since I don't talk about it much here. If you don't care, skip right on by to the next section...

I'd originally proposed this talk because I thought it looked fun. Later I passed it to Jesse Liberty since he works with Windows Phone all the time, but helped him write up the outline and sample code because I thought it looked like fun (and partly because I'd dumped the talk on him). Then when he found out the week before DevConnections that he'd be unable to attend, I requested to take the talk back, because it looked like fun. This stuff is just plain cool to work with, and I had a blast preparing and presenting on it.

While I don't do a lot of Windows Phone development, I've spent some time pair programming with Jesse on The Full Stack project, which includes a Windows Phone client. One of my main takeaways from that project was that it's really easy to get started with Windows Phone development, especially if you've done some Silverlight development - and I've done a good amount of Silverlight development. There are a few new concepts to wrap your mind around, but I was amazed how easy it was to get up and running.

Background Services - Start with the right mindset

You want your Windows Phone applications to do useful work in the background, but you don't want the background processes to affect the end user's phone experience. By experience, I mean:

  • You don't want them to interrupt or slow down foreground tasks (especially talking on the phone) in any way, ever
  • You don't want them to run down the battery
  • You don't want them to run up expensive bandwidth charges or interfere with foreground network usage
  • You don't want anyone to have to think about them at all

Rather than hope developers will keep the user and the above values in mind and do the right thing, Windows Phone background services provide a great framework for you to work within, and they automatically make sure you're playing within the rules. I think they've struck a great balance here, but when you're developing background services in Windows Phone, you need to keep this always in mind.  Your background services are most definitely managed, and they will play within the rules. It's important to have that straight from the beginning.

Overview of services

Windows Phone background services are easier to understand when you get the idea of how they all fit together. I mentally broke them down into three generic types, with some pre-built "specialist" agents to handle common background use cases.

Note: Some of this logical grouping is stuff I came up with on my own to make sense of all of the different options. It's not officially approved by anyone but me, but it's just a mental model to help you understand what's available. Technically, if you look at the ScheduledAction class hierarchy, Resource Intensive tasks fall right next to Periodic Tasks, but for the sake of understanding what the different types of tasks and actions do, I think it's easier to ignore that for a bit.

2011-11-22 17h10_37

Color coding explanation:

  • Purple are custom tasks
  • Green are pre-built, specialized tasks
  • Blue are general types

Scheduled or Resource Intensive?

Scheduled tasks are things that don't require many resources (e.g. CPU, network) and need to run on some kind of schedule. Resource intensive tasks do require resources, so they can't dictate when they'll run.

The Windows Phone operating system keeps background tasks from abusing resources by making decisions based on how resource intensive they are. Processes that require a lot of resources can only run when conditions are met (e.g. while charging or when battery power is high), and processes that run periodically or on a schedule can't use a lot of resources.

Whatever, you say. I'll do what I want when I want because I'm a rebel. But, no, it's not that kind of setup here in background task land. For stealing tools, cooler. If your task doesn't abide by the rules, it's terminated.

Resource Intensive Tasks

Resource Intensive agents run for a relatively long period of time when the phone meets a set of requirements relating to processor activity, power source, and network connection. An example here would be performing a long-running computation, or uploading a lot of data to a service.

Since by their nature these tasks are expected to use resources, they're only allowed to run when resources are plentiful, e.g.

  • External power required
  • Non-cellular connection required
  • Minimum battery power: 90%
  • Device screen locked
  • No active phone call
  • Can't run longer than 10 minutes

Built-in Resource Intensive Tasks

There are two built-in resource intensive task specialists - Background Audio and Background File Transfer. Since their use-cases are more defined, some of the above requirements are relaxed.

Note: I've decided to lump background audio and background file transfer under Resource Intensive tasks because they make some logical sense there - they do suck up resources, and they aren't scheduled. That's my logical grouping, it's not anything official.

Background Audio

Background Audio lets you queue and play audio while your device isn't active or even running. I showed two examples during my talk - one which queued up a bunch of tracks which continue to play when you navigate away, and another example which plays a ticking clock in a Pomodoro application to remind you that you're still "on the clock."

The architecture of Background Audio is fascinating. It takes a little bit to figure out who's doing what, but it's really well put together. First, meet the two main players:

Audio Player Agent

It's your job to create the Audio Player Agent. You can do that by adding a new project to your solution and selecting one of the two Windows Phone Audio Agent project types (Playback or Streaming).

2011-11-22 21h45_25

Of course, you can write the code by hand if you prefer, but there's little point. This project template adds the necessary references and drops a single class into your Audio Player Agent project - a class which extends the AudioPlayerAgent base class and handles two events:

OnPlayStateChanged - this is where you put the logic for when a track ends or is ready to be played

OnUserAction - this is where you respond to user input - things like play / pause / skip next / skip previous commands

The important thing to get here is that your Audio Player Agent class is completely responsive. Its only purpose is to respond to events.

Background Audio Player

There's only one Background Audio Player, and you don't own it. It belongs to the operating system, and you talk to it through its static BackgroundAudioPlayer.Instance property. Your application issues commands (requests?) to the Background Audio Player instance, which raises events in your Audio Player Agent.

So your application code talks to the Background Audio Player Instance, which talks to your Audio Player Agent - your application code never talks to the Audio Player Agent. This makes sense when you remember that your application may be tombstoned or closed immediately after talking to the Background Audio Player, which doesn't matter - the Background Audio Player calls into your agent without having to spin up your application. Here's the diagram from MSDN that shows this communication:

Note that the diagram shows the Background Audio Player is using two other operating system level components to play the music - the Zune Media Queue and the Universal Volume Control. This ends up giving a great experience to the end user with little work on your part: you queue up the audio, and the user can control the volume through a standard interface.

See the Background Audio Overview on MSDN for more information on how these parts work together.

Background Audio Tips

Here are a few good things to keep in mind when developing background audio applications.

  • For development, you can use F9 (volume down), F10 (volume up), and F11 (play/pause).
  • Your background audio can be either an internet URL or a file in Isolated Storage. If you have audio you need to move to Isolated Storage, see Jesse's post on how to do that.

Extra Credit: Background Audio Agent registration

Just because I'm one of those people who can't take "just because" for answer, I needed to know how the Background Audio Player knew how to find my application's Audio Player Agent. It turns out that's set up in your main application's WMAppManifest.xml (in the Properties folder). If you take a look at that, you'll see a section in there that lists tasks:

<Tasks>
  <DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
  <ExtendedTask Name="BackgroundTask">
    <BackgroundServiceAgent Specifier="AudioPlayerAgent" 
                            Name="AudioPlaybackAgent1" 
                            Source="AudioPlaybackAgent1" 
                            Type="AudioPlaybackAgent1.AudioPlayer" />
  </ExtendedTask>
</Tasks>

Background File Transfer

The Background File Transfer service lets you register files for upload or download, and it takes it from there. It waits until appropriate conditions are met - for example, it only transfers small files over cellular networks, waiting for wi-fi or wired connection to transfer larger files - and raises events which your application can handle if it's running. It's all very fire-and-forget.

A few things to be aware of here:

  • The service won't run until conditions are met. The operating system imposes some, and you can add additional restrictions. The important thing to realize here is that the conditions may never be met, so the file transfer will never happen. If you've requested a large file download which exceeds the cellular limits, but you have a user who never uses a wi-fi connection, they'll never get the file. So the responsibility is on your application to handle those exceptions.
  • Mango has great support for HTTP, so you can make use of headers like If-Modified-Since and ETAGs to optimize transfers.
  • You get both progress and completion events, so your UI can display status to users if they'd be interested.
  • You don't need a separate agent here. You register a TransferRequest with the service and subscribe to the events, but you don't need a service because the transfer service doesn't need you to respond to anything if your application's shut down.

Custom Resource Intensive Tasks

If you need to do something resource intensive - other than audio or file transfers - you can create your own Scheduled Task Agent. You do that the same way we added the Audio Player Agent previously - there's a project type just for that. These agents just have one method: OnInvoke. That's where you do all your resource intensive what-have-you. As I mentioned earlier, there are a lot of constraints on Resource Intensive Tasks, summarized in MSDN.

My main takeaway is that you can do some neat things with these, but you need to account for two things:

  • You don't know when - or if at all - your user's phone will run your task.
  • If your task misbehaves, it will be terminated. Just like that.

Here's how you'd register you Resource Intensive Task:

resourceIntensiveTask = new ResourceIntensiveTask(resourceIntensiveTaskName);
resourceIntensiveTask.Description = "This demonstrates a resource-intensive task.";
ScheduledActionService.Add(resourceIntensiveTask);

Scheduled Tasks

As with Resource Intensive tasks, you have a few options with scheduling. If you just want to notify the user, you can take advantage of some built in notifications (alarms and reminders); if you need to do something else you can create a custom Periodic Task.

Notifications

You've got two types here: Alarms and Reminders. Both are scheduled for some time in the future with a few lines of code, and that's it as far as your app is concerned. There are a few minor differences between the two:

  • Alarms will always have a title that says "Alarm" while Reminders can have a custom title
  • Alarms can play a custom sound, while Reminders will always play the system reminder tone
  • Tapping on an Alarm will launch the app and take you to the initial page of the application, as if it were just being launched. Reminders can include a navigation URI to a page inside your phone application, and it can contain querystring information as well.

Registering an alarm or reminder is pretty much identical, with the only difference being in supported properties. Example:

Reminder r = new Reminder("Break_Over");
r.Title = "Back To Work";
r.Content = "Break's Over!";
r.BeginTime = DateTime.Now.AddSeconds(10);
r.NavigationUri = NavigationService.CurrentSource;
ScheduledActionService.Add(r);

Periodic Tasks

Periodic Tasks aren't really scheduled in the way I first assumed. They can be set to run as often as 30 minutes, but that time may drift by as much as 10 minutes. They may not run every cycle, depending on how busy the operating system is. They'll be terminated if they run longer than 25 seconds, but may be terminated sooner if the operating system decides it needs to.

The point is that the Periodic Task system isn't a scheduler. It's a way to do light, low resource work in the background - small internet communications, updating a tile, etc. They're great for keeping the users phone up to date with nice to have information, but you have to assume that the task may run less often than you'd hoped, or potentially not at all.

Creating a periodic task is really easy - it's the same idea as creating a resource intensive task. You add a Scheduled Task Agent to your project, then register it with the Scheduled Action Service like this:

periodicTask = new PeriodicTask(periodicTaskName);
periodicTask.Description = "This demonstrates a periodic task.";
ScheduledActionService.Add(periodicTask);

A couple of tricks

Removing tasks before adding them

There are a few tricks to be aware of. First, the Periodic and Resource Intensive Tasks are registered by name - a string. So the above code I showed for both of them is overly simplistic - it will fail if you try to schedule the same task twice. The proper pattern is to find and remove the task before adding it:

periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
if (periodicTask != null)
{
  ScheduledActionService.Remove(periodicTaskName);
}

periodicTask = new PeriodicTask(periodicTaskName);
periodicTask.Description = "This demonstrates a periodic task.";
ScheduledActionService.Add(periodicTask);

Launch for testing

Many of these things would be tough to test in normal conditions. For example, a there's no way I want to wait around 30-40 minutes to see if my Periodic Task will run correctly. Fortunately, you can use LaunchForTest to schedule a task when you're in debug mode.

#if DEBUG_AGENT
  ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(60));
#endif

Toast

If you're running background processes, you may need to alert your users when things happen - completed task, failed task, significant task progress, etc. You can do that using ShellToast.

ShellToast toast = new ShellToast();
toast.Title = "Have some toast";
toast.Content = toastMessage;
toast.Show();

Slides, Podcast, Code

Here are the slides for my presentation at DevConnections:

Here's the podcast with Jesse Liberty, Peter Torr, and me talking about background services and agents in Windows Phone:

Yet Another Podcast #52 - Peter Torr on Windows Phone Multitasking

Code samples from my demos are available here.

Jesse and Peter have both written about Windows Phone multitasking topics on their blogs:

Posted by Jon Galloway | with no comments
Filed under:

15 Pragmatic JavaScript Tips for ASP.NET Developers

Here are 15 pragmatic JavaScript tips for ASP.NET developers from my recent presentation at DevConnections 2011 (Las Vegas).

The goal here is pragmatic tips - things you can use right away. Three or four are specific to ASP.NET Web Forms, the rest are pretty cross-cutting and in some cases apply to any web development platform. These are pragmatic tips, not advanced JavaScript development or coding practices, although I did sneak in a bit of SignalR, Node.js, and CoffeeScript at the end. If you're looking for coding practices, I'd highly recommend Elijah Manor's MIX11 talk: Good JavaScript Habits for C# Developers.

Damian Edwards has given a similar talk several times over the past year and kindly shared his samples and advice - his talks are all available here. His talks covered a lot of great information, and my updated talk also included some future / edge stuff, like RIA/JS, Visual Studio 11, ASP.NET 4.5, Node.js, and CoffeeScript. Since I was covering a ton of information in an hour, I opted to structure this talk as a series of 15ish tips, building from the simple and easy material to, well, stuff like SignalR and Node.js with WebMatrix and iisnode.

Slides are here:

I set up a new repo for presentations (slides and code) on Github; here's the sample code for my demos. My presentation wasn't filmed, but Damian's talks at MIX and TechEd were. Links to those videos are in the presentation section of his blog.

Okay, enough talking, more tips. Here we go:

Tip 1: If you’re using Ajax Control Toolkit, get the newest releases

It's been a while since I used the Ajax Control Toolkit, but it's still apparently very popular (substantiated by a show of hands at the presentation). The tip here is that - if you're still using Ajax Control Toolkit - you should be aware that there are regular new releases, and that they're available via NuGet.

Recent releases include several new controls, including Gravatar, Twitter, and a new HTML editor. The new releases also include top fixes from the issues list, and there's a real emphasis on quality - as shown by the automated browser testing with QUnit. You can read more about recent updates on Ajax Control Toolkit from Stephen Walther.

The overall guidance from the ASP.NET team is that they're recommending jQuery for client-side coding. That's where future focus, project templates, code samples, etc., will be. However, if you're using Ajax Control Toolkit, you should be on the latest releases. It's easy to do now, since Ajax Control Toolkit can be installed and updated via NuGet.

Tip 2: Get to know jQuery

Sure, no surprise there. All web developers should know about jQuery, and if you're not using it you should have a pretty good reason. Here are the top advantages I listed:

  1. DOM abstraction
  2. Selector engine (I explained selectors using this Interactive jQuery Selector Tester page)
  3. Plugin ecosystem
  4. Leverage CDN’s (talked about how end users have to wait for your custom scripts to download, while jQuery is very likely cached by their browser)
  5. Included in Microsoft templates (showed that File / New Project will put jQuery in your application)

I pointed out that JavaScript is beautiful and elegant, but sometimes extremely tricky. We looked at variable hoisting as an example. The point is that JavaScript can be a bit tricky, and writing your own libraries when jQuery does it better is an unnecessary code liability to take on.

Tip 3: Install and Update jQuery via NuGet

ASP.NET MVC 3 already includes jQuery as a NuGet package, so it's easy to upgrade when a new version comes out. I showed how to remove the jQuery scripts from an ASP.NET Web Forms application and add jQuery via NuGet to get that same upgrade experience. We looked at adding jQuery plugins via NuGet, too.

Tip 4: Know how to find and use jQuery plugins

I explained what plugins are used for, and showed three great ways to find and use jQuery plugins:

I showed the jQuery theme support, and we hooked up a few jQuery UI datepickers to ASP.NET textboxes.

Tip 5: Use jQuery UI via Unobtrusive Wire-up

Damian's written a nice jQuery plugin to wire up jQuery UI widgets via HTML5 data- attributes, and it works for standard HTML and ASP.NET Web Forms controls. Here's an example:

<asp:TextBox runat='server' ID='startDate'
    data-ui-fn='datepicker' />
<div class='status-box' data-ui-fn='draggable resizable'>
    I'm a Drag and Droppable, resizable content area.
</div>
Joe Stagner has a full walkthrough on this here: Unobtrusive JavaScript in your ASP.NET pages

Tip 6: Write your own jQuery plugins

We walked through turning some of our jQuery code into a plugin, making use of the jQuery Code Snippets for Visual Studio 2010.

Plugins offer some great benefits, even if you never plan to distribute your plugin:

  • Code encapsulation
  • Reuse throughout one site or a number of projects (I talked about an example where my team bundled common jQuery code into plugins, and we were later able to leverage them from content input via CMS users)
  • Standard, tested modularization system that's designed to work well with jQuery

A good way to get started with writing your own jQuery plugins is the Plugin Authoring Tutorial on the jQuery site. It's really well written, starting with simple cases and slowly introducing advanced topics and best practices.

Tip 7: Take advantage of Visual Studio’s JavaScript support

I showed off some of the JavaScript editing and Intellisense features that are included in Visual Studio 2010. A lot of people aren't aware that the Intellisense infers type and can handle dynamic variables, loops, etc. Neat stuff.

See Scott Guthrie's post, JavaScript Intellisense Improvements with VS 2010, for a nice walkthrough.

Tip 8: Get ready for Visual Studio 11 JavaScript features

Okay, Visual Studio 2010 has some nice JavaScipt editing features, but Visual Studio 11 Developer Preview is a huge advance here. It's actually using the same engine that's used in the Internet Explorer Developer Tools, and Visual Studio 11 adds a lot of goodness like implicit references (configurable by editing a JavaScript file), brace matching, outlining, etc.

More on those features here: http://bit.ly/vs11javascript

Since Visual Studio 11 Developer Preview works side-by-side with Visual Studio 2010, you can start using those features today. Yes, it's pre-release, but I'll give it the Works On My Machine certification - I've been using Visual Studio 11 Developer Preview side-by-side with Visual Studio 2010 since //build and it's been working great. Visual Studio 11 Developer Preview starts up so quickly, I'm often using it in cases where I would have used Notepad++.

Tip 9: Use the Visual Studio 2010 JScript Editor Extensions

Ah, you say, Visual Studio 11 Developer Preview is neat, but that's not what I call pragmatic. It's not out yet!

Fine, there are some great Visual Studio extensions which give you a lot of the great features in Visual Studio 11 in Visual Studio 2010. That's no accident, some (like the Web Essentials extension) are written by the PM's who are driving the Visual Studio 11 features.

The Visual Studio JScript Editor Extension adds a lot of the Visual Studio 11 JavaScript editing goodies to Visual Studio 2010. Things like:

  • Brace Matching
  • Outlining / Code Folding
  • Current Word Highlighting

Is this pragmatic? Sure! It's a free, quick install, and if you do any JavaScript editing in Visual Studio it will pay for itself in no time!

Tip 10: Use ASP.NET 4 ScriptManager features

Okay, if you're using ASP.NET 4.0 Web Forms, you need to know about the new features in ScriptManager. In my talk I demo'd how easy it is to use CDN's and how to register scripts like a Ninja Pirate Honey Badger with ScriptManager.ScriptResourceMapping. Script Resource Mappings offer a number of benefits:

  • You can register a library like jQuery by a version independent name ("jQuery"), so upgrading jQuery versions means that you only need to update the mapping in one place, rather than throughout your code
  • Using Script Resource Mappings really helps in cases where you may be referencing a library multiple times (e.g. in a page and in a multi-instance user controls within that page) since it will only include the script once

Pragmatic? Yes! This shipped with ASP.NET 4.0 (April 2010), and taking advantage of resource mappings and automatic CDN usage means you'll have more maintainable, higher performing, better script references with minimal effort.

Tip 12: Use RIA/JS for WCF services

RIA/JS is a set of jQuery plugins for accessing RIA Services DomainService and OData services. My demo - for this (which was unfortunately pretty rushed) covered the BigShelf sample from the RIA/JS team, which shows how you can use WCF RIA Services to access WCF services from a browser using a really efficient JavaScript library. It includes full featured services, and your service calls are all using really light-weight JSON.

The best way to get up to speed on what's new - and coming - in WCF RIA Services is to watch Dinesh's talk at BUILD. Jeff Handley posted a good summary of the updates for //build which explains what's been released and what's in the works. The short summary is that if you're calling into WCF services from the browser, you should strongly consider using RIA/JS (Mea culpa).

Tip 13: Use SignalR for long-polling

Yeah, this is tons of fun. SignalR is a "smart" way to do long-polling with ASP.NET. For an example, I ran the StackExchange chat application and showed that each request was polling - sending a bunch of repetitive requests to the server, asking "Anything new? How about now? Now? Anything? Hey, anything new?"

HTTP Short Polling

SignalR is a nice system (both client and server libraries available) which implements long polling, in which the browser makes a request and the server waits to respond (keeping the connection) open until there is new information to send to the client.

HTTP Long Polling with SignalR

You could implement this pattern on your own if you worked at it, but there's a good chance you'd be tying up threads on the server for each open request. Some smart guys on the ASP.NET team have set up this library to leverage stuff like the task parallel library, websocket support (if the browser supports it), takes advantage of async / await, etc.

Is this pragmatic JavaScript? Absolutely! This is real, working code, you can install SignalR immediately via NuGet, and it improves scenarios in which the client is waiting for updates from the server because it's more performant and will return information to your clients immediately, rather than waiting for the next time they poll. The source includes some great samples, including some multi-user applications like chat and a collaborative shape / drawing example.

You can find out more in Scott Hanselman's recent post, Asynchronous scalable web applications with real-time persistent long-running connections with SignalR.

Tip 14: Server-side JavaScript with iisnode and Node.js

Node.js is a popular system for writing server-side code in JavaScript, and it's optimized for high performance and asynchrony. I wrote a big post on it recently: Using Node.js in an ASP.NET MVC application with iisnode.

Is this pragmatic? Well, this one is stretching things a bit, but I couldn't help myself. You can use Node.js in IIS using iisnode (even integrating it into an ASP.NET site, since iisnode runs as a standard IIS handler), and it works today. The Node.js community is big, and there are a ton of great packages available now. Is it likely people will start integrating Node.js into their ASP.NET Web Forms applications any time soon? Hard to say. One advantage is that you can reuse JavaScript code on client and server, which could be a big advantage if done right.

Tip 15: Adventurous? Keep an eye on CoffeeScript

Early on, I talked about the fact that JavaScript is powerful, but can be a bit tricky. Some of this is due to the fact that JavaScript is a dynamic, prototype based, weakly typed language masquerading under Java syntax. CoffeeScript is a "little language" that compiles into JavaScript:

Underneath all those awkward braces and semicolons, JavaScript has always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.

One benefit of CoffeeScript is that it automatically prevents you from accidentally shooting yourself in the foot due to strange language quirks. If you're writing a lot of JavaScript, CoffeeScript is definitely worth a look. I recently wrote An introduction to CoffeeScript which explains how it works and how to get started.

What about you?

Okay, that's my list. Got any tips you'd like to share?

More Posts