Don’t use PhoneApplicationService.State[] in Mango

People who tell you, unequivocally, to not use a certain service in a platform are usually wrong. What they really mean to say is “don’t use service X under this and that circumstances”. However, like in politics, a simple bold statement gets more attention that a true one.

So here’s the more complete and actually true title of this post:

“Don’t use PhoneApplicationService.State[] in Mango for large pieces of data (say, 50k and more) or if the serialization/deserialization process of the data is complicated and may affect your application state”

If you do, you will use a bunch of memory you don’t really need and also cause your reactivation (when the user switches to your app, or if the user backs into it) to be slower.

Context

With Mango, and Fast Application Switching (FAS), there’s a subtle change in how applications behave on activation. To learn more about that, go to msdn – you will find nice pictures that will explain exactly what happens and what a dormant application is and how to properly handle the Activate event on the app.

History

Pre-mango, this was a useful mechanism by which you could save your transient data so that you can come back from tombstoning of your application (you can read about tombstoning in that article above). Essentially, in WP7.0, the application was given a chance to save its state so that it may come back to life when you “back” into it and look like you did not leave it. The three primary ways for doing this are page state (these are used to save objects that you want back when backing into a page), query parameters on a page uri (for primitives that do not go over a certain length – they will always be in the NavigationContext.Query property of the page) and PhoneApplicationService.State which is used for app-global state that needs to be resurrected when the app is activated.

So what changed with mango?

With Mango, for the most part, tombstoning no longer happens with your app (unless your navigation history is pretty darn big). Because applications are kept dormant in memory, there’s no need to dehydrate them using the various states we talked about (you probably still want to use them in the event that you ARE tombstoned though – you will probably not pass certification if you don’t). Which brings us to the broken bit here…

Mango will dehydrate your PhoneApplicationService.State saved objects regardless of whether you are going back to a dormant application or being rehydrated from a tombstoned state. To illustrate, take the following example:

Code Snippet
  1. private void Application_Deactivated(object sender, DeactivatedEventArgs e)
  2. {
  3.     PhoneApplicationService.Current.State["obj"] = m_test;
  4. }

In here, when the app goes away and is getting deactivated, we go and save an object into the state. m_test is of the following type:

Code Snippet
  1. public class TestObject
  2. {
  3.     public TestObject()
  4.     {
  5.         TestInfo = "test";
  6.     }
  7.     public string TestInfo { get; set; }
  8. }

Now, generally, this is how your “Activate” event callback should look like:

Code Snippet
  1. private void Application_Activated(object sender, ActivatedEventArgs e)
  2. {
  3.     if (e.IsApplicationInstancePreserved)
  4.     {
  5.         return;
  6.     }
  7.  
  8.     m_test = (TestObject)PhoneApplicationService.Current.State["obj"];
  9. }

The first “if” is a Mango addition – if the app was just dormant, we don’t need to actively restore state. Great.

But here’s the rub. When you go back to the app, even if it was just dormant, a new TestObject will be constructed – even though it’s never going to be needed. If your saved state takes time to serialize/deserialize, this will affect reactivation of your app and will also take memory in the app that you are not really going to use.

Alternatives

Still with us? There aren’t a lot of good alternatives… If all you save in the state is a bunch of bools or even simple classes, feel free to continue doing that and ignore this whole post. However, if you store a lot of state in there, consider saving the state into isolated storage on deactivate – you will then have control over whether or not you need to read the data back.

About these ads
This entry was posted in Dev, Windows Phone. Bookmark the permalink.

4 Responses to Don’t use PhoneApplicationService.State[] in Mango

  1. Pingback: Don’t use PhoneApplicationService.State[] in Mango

  2. Pingback: Don’t use PhoneApplicationService.State[] in Mango « Silverlight News

  3. Peter Torr says:

    Or keep the actual data in a static so that when the system re-creates a new object it just re-connects to the existing static… no wasted memory and no time spent reading / writing to disk in the case of not being tombstoned

    • shaharprish says:

      Not really. When the app goes to the background, its in a dormant state, but the system can (and will) kill the app if more resources are needed. When that happens everything that’s static – the entire process – dies and goes away. The statics will not be there. The only way to then survive a shutdown is to go to isolated storage that is persistent between runs of the app.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s