Using Windows Phone Task Launchers “Correctly” In XNA

August 2nd, 2012 | Posted by Stephane in Programming

If you’re developing for Windows Phone 7, you’ve probably heard (or even made use) of Microsoft’s incredibly useful Windows Phone Task Launchers (and if you haven’t, well sit down and listen up, Sparky, you won’t want to miss this). These launchers allow you to easily run various useful tasks like these:

  • Taking your users to your game’s review and rating page on the Marketplace
  • Launching the default browser and opening your app’s website
  • Sharing a message about your game on various social networks

And when I say ‘easily’ I mean literally in two lines of code, which is awesome, but it’s a little misleading because there’s a problem…

Crash And Burn

The naive, copied-straight-from-msdn method of coding would probably lead you to making a “Rate Me!” button that looks something like this:

// Rating Button and Task
Button ratingButton = new Button("Rate Me!");
MarketplaceReviewTask ratingTask = new MarketplaceReviewTask();

ratingButton.OnClick += (sender, args) => ratingTask.Show();

Odds are, you can crash the majority of apps and games on the Marketplace by double-tapping such a button. The reason is that these tasks take control of the phone away from your app or game, and give it instead to whatever task you launched. Problem is, the first thing any of these tasks will do is check to see if your app still has control so it can steal it. If you double-tap fast enough, you’ll give away control on the first launch, and the second launch will throw an InvalidOperationException because it can’t get control anymore!

Doing It “Right”

Luckily, we’re lazy engineers, and so we quickly found the easiest (and dirtiest) solution. Sure, you could store a boolean somewhere in your app that disables the button’s event handler as soon as it’s clicked, and then re-enables it when the app resumes, but that’d be, like, work, man! Instead, you can apply the KISS principle and come up a hack that gets the job done anyways: just wrap it in a try-catch block, as shown below.

// Rating Button and Task
Button ratingButton = new Button("Rate Me!");
MarketplaceReviewTask ratingTask = new MarketplaceReviewTask();

ratingButton.OnClick += (sender, args) =>
{
    // Safety first!
    try
    {
        ratingTask.Show();
    }
    catch (Exception) { /* No one cares */ }
};

Now, let’s repeat the same scenario as above, where a user double-taps the “Rate Me” button in quick succession: the first tap will launch the task normally and steal control from the app, and then the second launch will throw an exception, which will get eaten and ignored. So, thanks to C#’s delicious unchecked exceptions, everything proceeds as though the second one didn’t happen at all, the application doesn’t crash, and both you and the users are happy campers.

Proper programming practice? Nope. Anyone care? Nope.

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

2 Responses



Leave a Reply

Your email address will not be published. Required fields are marked *