I looked all over the internet to find a good solid article on Tombstoning in Wp7, however it seemed like everyone had a different perspective and each came up a little short of what I wanted. The biggest problem is defining what Tombstoning really is. So lets begin with that.
Tombstoning – Using the Deactivation event for the application in order to save state that will be restored during the Activation event.
It’s as simple as that. Now how can we save state? There are a few options to accomplish this.
Local Database (Persistent)
Working with Paul Rohde and Travis Schilling we created an application that utilized the local database for our application. It was pretty nice. It’s completely accessed by LINQ to SQL as far as we can tell. Travis was the man behind all of that work, and he seemed to say it wasn’t difficult once you understand how the DB is created.
In Isolated Storage you have the option to save key-value paired rich objects in IsolatedStorageSettings.ApplicationSettings. This dictionary has a TryGetValue<T>(string name) method that is very useful. This makes for very quick saves of complex object graphs. There is also the option to save files using IsolatedStorageFile and IsolatedStorageFile. I have not used these, but they seem straight forward enough. Microsoft, however does not suggest using any IsolatedStorage options when trying to Tombstone. Why? It’s slower than the alternative PhoneApplicationService.Current.State dictionary.
The PhoneApplicationService is the preferred way to Tombstone your application according to a post from Microsoft. It’s faster than any kind of persistent storage according to that post. You would use PhoneApplicationService.Current.State to add and read transient data. The downside to this dictionary is that the TryGetValue method is not generic by default. We’ll have to create an extension method to have it work the same as IsolatedStorageSettings’ TryGetValue<T>().
What data do I save?
This question, I think, used to be more cut and dry. I remember creating an application pre-Mango (7.5) and if you left the application then went back to the application no data would be persisted because the application was closed not Tombstoned. However I’m seeing that in Mango the current page being viewed when the application is deactivated is not reliably lost. A strange statement, however true. When I deactivate my application I’d expect the VisualTree and object graph to be lost, thus requiring me to save all of the required data during the Deactivated event so it could be restored during the Activation event. I’m not experiencing this. I’m seeing the object graph being kept around as well as associated VMs. Do I need to save this data since I can see it’s not being lost? After talking with Tim Askins we’ve decided it’s best to save the data even if we don’t need to restore it. The saying, “Better safe than sorry” comes to mind.
Best Practices and Cautions
- Save all data that can be treated as Session data in PhoneApplicationService and store all permanent data in your preferred form of persistent storage (Database or IsolatedStorage).
- Don’t try to call any web services that would normally be used to store the data if the application continued to run. If data needs to be sent to a web service, enable your application with a background task.
- Remember you only have 10 SECONDS MAX to be fully Tombstoned before the OS will close your app.
- Note that you should make sure all of your objects being stored in PhoneApplicationService or IsolatedStorage are marked as DataContract and each property is a DataMember. We also saw this was not really enforced, but I think it’s best practice to do this. Again, “Better safe than sorry.” Plus, Microsoft says that it is required.
- Save persistent data as it’s changed rather than waiting for the application to be deactivated.
Launching/Closing vs. Activating/Deactivating
The Launching and Closing events should be used to load and save persistent data. Activating and Deactivating events should be used to load and save persistent and transient data. The less persistent data you must handle during Activation and Deactivation the better. Persistent storage is slower than transient storage and therefore reduces the user experience.
After scoping out the web I’ve found the following links very helpful. Each have different perspectives and insights that I think are worth mentioning as part of the great whole called Tombstoning.