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.
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.
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:
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:
Now, generally, this is how your “Activate” event callback should look like:
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.
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.