While implementing tombstoning in a Windows Store app I recently ran into this issue. Some pages tombstoned and resumed perfectly, while some other pages gave this error when tombstoning
This one took me a while to figure out, but I finally found the problem. But before diving into the solution, I’ll show you how I got to this error.
If you’re reading this, I’m assuming you know about the app lifecycle and tombstoning so I’m not going to explain that. To demonstrate the problem I created a blank app, added in a basic page so that Visual Studio included the NavigationHelper and SuspensionManager classes.
In the app I have two pages, Mainpage.xaml and Page2.xaml. Mainpage has a button that takes me to Page2. The navigation happens with the build-in NavigateToPageAction, easily dragged and dropped onto the button from Blend.
This creates an EventTriggerBehavior on the button that triggers a NavigateToPageAction
All that’s left to do is set the target page in the NavigateToPageAction properties
And we’re done. We’ve just created an app with a button that navigates to another page without writing any code, pretty neat and easy stuff right?
Next thing I did was follow this MSDN article that shows in a few easy steps how to implement tombstoning so that if the app tombstones on a certain page and the user switches back to the app, it reloads that page. It worked and all was well. That is, until I implemented the tombstoning on a page that was navigated to using the NavigateToPageAction. tombstoning that page always resulted in the error shown in the screenshot at the beginning of this post (and it took me a few hours to discover that the action was at fault here). Let’s have a closer look to see what’s actually happening here.
Navigation and NavigationParameters
When navigating between pages we can pass parameters. In Windows Store the signature of the Frame.Navigate function is this
Navigate(Type, Object, NavigationTransitionInfo)
The parameter is of type Object, meaning we can pass in anything we’d like. Pretty powerful right? Right, except when tombstoning.
At a certain point in the Tombstoning process this snippet of code gets executed
- private static void SaveFrameNavigationState(Frame frame)
- var frameState = SessionStateForFrame(frame);
- frameState["Navigation"] = frame.GetNavigationState();
This will save the current NavigationState of the pages into a dictionary. The caveat here is that this only works with primitive types. If we pass strings or integers as parameter this will work, no problem. If we pass in an object of type MyClass we will get the SuspensionManager failed error.
Okay cool, that’s all great, we found a possible source of the error. But, we’re not passing in any parameters to the page, so why are we getting the error? Let’s set a breakpoint in the OnNavigatedTo method in Page2.xaml.cs
Well well, would you look at that. Our NavigateToPageAction snuck in a little parameter without telling us, and that parameter is not a primitive type so we get a crash.
The fix + conclusion
The fix is actually really easy, don’t use NavigateToPageAction. Yes just don’t use it. I know it’s really fast and easy but it breaks the entire tombstoning thingy. I fixed it by calling Frame.Navigate (Type) from the button’s click event.
I’ve uploaded a sample with two buttons on my OneDrive, one button has the crashing effect, the other one doesn’t.