/// <summary> /// Save the current <see cref="SessionState" />. Any <see cref="Frame" /> instances /// registered with <see cref="RegisterFrame" /> will also preserve their current /// navigation stack, which in turn gives their active <see cref="Page" /> an opportunity /// to save its state. /// </summary> /// <returns>An asynchronous task that reflects when session state has been saved.</returns> public static async Task SaveAsync() { try { // Notify Root Navigator and AuthenticationService that we are suspending if (RootNavigatorLocator.IsAvailable) { EventFns.Forward(RootNavigatorLocator.GetPart(), new Suspending(SessionState)); } if (AuthenticationServiceLocator.IsAvailable) { EventFns.Forward(AuthenticationServiceLocator.GetPart(), new Suspending(SessionState)); } // Save the navigation state for all registered frames foreach (var weakFrameReference in RegisteredFrames) { Frame frame; if (weakFrameReference.TryGetTarget(out frame)) { SaveFrameNavigationState(frame); } } // Serialize the session state synchronously to avoid asynchronous access to shared // state var sessionData = new MemoryStream(); var serializer = new DataContractSerializer(typeof(Dictionary <string, object>), KnownTypes); serializer.WriteObject(sessionData, _sessionState); // Get an output stream for the SessionState file and write the state asynchronously var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(SessionStateFilename, CreationCollisionOption.ReplaceExisting); using (var fileStream = await file.OpenStreamForWriteAsync()) { sessionData.Seek(0, SeekOrigin.Begin); await sessionData.CopyToAsync(fileStream); await fileStream.FlushAsync(); } } catch (Exception e) { throw new SuspensionManagerException(e); } }
/// <summary> /// Restores previously saved <see cref="SessionState" />. Any <see cref="Frame" /> instances /// registered with <see cref="RegisterFrame" /> will also restore their prior navigation /// state, which in turn gives their active <see cref="Page" /> an opportunity restore its /// state. /// </summary> /// <returns> /// An asynchronous task that reflects when session state has been read. The /// content of <see cref="SessionState" /> should not be relied upon until this task /// completes. /// </returns> public static async Task RestoreAsync() { _sessionState = new Dictionary <String, Object>(); try { // Get the input stream for the SessionState file var file = await ApplicationData.Current.LocalFolder.GetFileAsync(SessionStateFilename); using (var inStream = await file.OpenSequentialReadAsync()) { // Deserialize the Session State var serializer = new DataContractSerializer(typeof(Dictionary <string, object>), KnownTypes); _sessionState = (Dictionary <string, object>)serializer.ReadObject(inStream.AsStreamForRead()); } // Notify Root Navigator and AuthenticationService that we are restoring if (RootNavigatorLocator.IsAvailable) { EventFns.Forward(RootNavigatorLocator.GetPart(), new Restoring(SessionState)); } if (AuthenticationServiceLocator.IsAvailable) { EventFns.Forward(AuthenticationServiceLocator.GetPart(), new Restoring(SessionState)); } // Restore any registered frames to their saved state foreach (var weakFrameReference in RegisteredFrames) { Frame frame; if (weakFrameReference.TryGetTarget(out frame)) { frame.ClearValue(FrameSessionStateProperty); RestoreFrameNavigationState(frame); } } } catch (Exception e) { throw new SuspensionManagerException(e); } }