WP7 Simplified: CoreApplicationService (Tombstoning)

This post brings closure to coverage of the CoreApplicationService (CAS) in this series titled WP7 Simplified. The final topic to cover is how the CAS handles tombstoning. Before getting into that let’s discuss what tombstoning is first. There are a couple of different terms to be familiar with that all refer to the tombstoning process: App Deactivation, Fast Application Switching, Tombstoning.

App Deactivation

When ever a user navigates leaving the app, except when they use the back button to close the app, the app is deactivated. All of the application state is stored in memory and app execution has 10 seconds to pause (Read the very last caution in the documentation). During deactivation it is important to store any transient and persistent state/data. From this state the application can be activated without losing any state in which case little if any state needs to be restored because the OS didn’t dispose of any part of the app state. The app could also be tombstoned which means that all state will need to be restored, but the application can still be activated. Finally the app might be completely closed by the OS thus requiring a fresh start.

Fast Application Switching

When an app is activating and the OS preserved state, the app should not attempt to do a full state restore, but instead should leverage the fact that the OS preserved the app’s previous state.

Tombstoning

If an app is tombstoned it means that all app state has been removed from the OS memory. This is why it is important for developers to store app state in transient or persistent data stores during app deactivation. When an app is activated from being tombstoned it should appear in the exact same state it was in before the user deactivated the app. It should also look the same as if the app had utilized Fast Application Switching.

For a much better explanation of these topics and some coverage of the difference between what persistent and transient data stores are available in Windows Phone please read my post Windows Phone 7 – Tombstoning.

Handling Tombstoning in CoreApplicationService

In the CAS only transient data is handled. We use DataProviders for persistent data. When deciding what transient data needs to be stored for tombstoning remember that we need to be able to restore the app during activation to the exact same state it was left in. Think of Leave No Trace from Boy Scouts and camping, we don’t want to leave any trace that the app was ever deactivated or tombstoned. Also, keep in mind when storing full objects that the object reference after retrieving a tombstoned value will be different than the object reference that was stored. If the reference needs to be the same the object should be stored in a persistent data store that should hand out the same reference for that object each time it is requested. We store values for tombstoning with the CAS using the following API.

public void StoreTombstoningValue(string key, object value)
{
	PhoneApplicationService.Current.State[key] = value;
}

public bool TryRetrieveTombstoningValue<T>(string key, out T value, bool clearKey = false)
{
	object tempObj;
	var exists = PhoneApplicationService.Current.State.TryGetValue(key, out tempObj) && tempObj is T;
	value = exists ? (T)tempObj : default(T);

	if (clearKey)
	{
		ClearTombstoningValue(key);
	}

	return exists;
}

public void RemoveTombstoningValue(string key)
{
	PhoneApplicationService.Current.State.Remove(key);
}

Store Tombstoning Value

Windows Phone provides developers with the PhoneApplication.Current.State dictionary which will survive as long as the app is not closed. Here is where we store all transient data.

Try Retrieve Tombstoning Value<T>

When retrieving a value we wanted to streamline the experience. Thus, this method is generic and does all the checks and casts each time a value is requested. It reports weather the value was found and cast correctly. It optionally takes in a parameter indicating to clear the value out of the State dictionary.

Remove Tombstoning Value

After retrieving a tombstoning value for the last time it should be removed to decrease memory usage.

Quick Tip of What to Store for Tombstoning

As much as possible only store object Id’s instead of the full objects. Even if at the moment the reference to that object doesn’t matter it may matter down the road. The naming of these methods is also very important. It is strongly suggested to not use the State dictionary to store objects during navigation. While it is true that a full object can be stored in the State dictionary before navigation for the next page to access after navigation, the object references are different because the State dictionary serializes and then deserializes all objects being stored then retrieved. This fact hurt one of our last projects. Once we had a grip on this principle we were OK, but until then bug after bug would manifest and they were difficult to track down.

Conclusion

Nothing super fancy this time. The motivation to include this functionality in the CAS was the constant repetition of the code in TryRetrieveTombstoningValue<T>(). It has helped clean up our code base quite a bit. This post also concludes code coverage of the CAS. The CAS is a very key component to any Windows Phone development. We’re excited to hear how you use it or how the principles discussed around it have helped you. Leave some comments to let us know. Next in the series we will be covering PageViewModel which works closely with ViewBase which we discussed in the previous post of this series WP7 Simplified: CoreApplicationService (Navigation).

One thought on “WP7 Simplified: CoreApplicationService (Tombstoning)

  1. Pingback: Simplifying the Windows Phone development experience! Codename: LionHeart | InterKnowlogy Blogs

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>