Nein es geht nicht um Frührente. der Lebenszyklus von Windows 8 METRO Anwendungen etwas eigenwillig. Kurz gesagt, kann man das Betriebssystem einen in den Hintergrund gelegte Anwendung aus dem Betriebssystem Sheduler entfernen. Der Modus nennt sich suspended.
warum und wieso dauert etwas länger zu erklären. Relevant ist, was man aus Coding Sicht tun muss.
Eigentlich muss man gar nichts tun. Die Anwendung wird ja nicht geschlossen, insofern kommt sie in dem Status zurück wie man sie zuletzt gesehen hat. Eine Textbox beinhaltet noch immer den Text. Aber Windows 8 hat das rechteine Suspended APP komplett zu entfernen. Ich habe das zwar noch nie gesehen, aber bei kommenden ARM Geräten mit wenig Arbeitsspeicher wird das wohl passieren.
Sämtliche Beispiele aus dem SDK enthalten eine Hilfsklasse die sich SuspensionManager nennt.Ich kopiere die aktuell in meine Projekte, auch wenn sie nicht optimal ist.
Module SuspensionManager
Private sessionState_ As New Dictionary(Of String, Object)
Private knownTypes_ As List(Of Type) = New List(Of Type)
Private Const filename As String = "_sessionState.xml"
' Provides access to the currect session state
Public ReadOnly Property SessionState As Dictionary(Of String, Object)
Get
Return sessionState_
End Get
End Property
' Allows custom types to be added to the list of types that can be serialized
Public ReadOnly Property KnownTypes As List(Of Type)
Get
Return knownTypes_
End Get
End Property
' Save the current session state
Public Async Function SaveAsync() As Task
' Get the output stream for the SessionState file.
Dim file As StorageFile =
Await ApplicationData.Current.LocalFolder.CreateFileAsync(filename,
CreationCollisionOption.ReplaceExisting)
Dim raStream As IRandomAccessStream =
Await file.OpenAsync(FileAccessMode.ReadWrite)
Using outStream As IOutputStream = raStream.GetOutputStreamAt(0)
' Serialize the Session State.
Dim serializer As New
DataContractSerializer(GetType(Dictionary(Of String, Object)))
serializer.WriteObject(outStream.AsStreamForWrite, sessionState_)
Await outStream.FlushAsync
End Using
End Function
' Restore the saved sesison state
Public Async Function RestoreAsync() As Task
' Get the input stream for the SessionState file.
Try
Dim file As StorageFile =
Await ApplicationData.Current.LocalFolder.GetFileAsync(filename)
If file Is Nothing Then
Exit Function
End If
Dim inStream As IInputStream = Await file.OpenSequentialReadAsync
' Deserialize the Session State.
Dim serializer As New DataContractSerializer(GetType(Dictionary(Of String, Object)))
sessionState_ = CType(serializer.ReadObject(inStream.AsStreamForRead),
Dictionary(Of String, Object))
Catch ex As Exception
' Restoring state is best-effort.
If it fails, the app will just come up with a new session.
End Try
End Function
End Module
In der Applikation Klasse app.xaml.vb wird dann diese aufgerufen wenn die Anwendung schlafen geht oder wieder aufwacht.
Protected Async Sub OnSuspending(ByVal sender As Object,
ByVal args As SuspendingEventArgs) Handles Me.Suspending
Dim deferral As SuspendingDeferral = args.SuspendingOperation.GetDeferral
Await SuspensionManager.SaveAsync
deferral.Complete()
End Sub
Protected Overrides Async Sub OnLaunched(ByVal args As LaunchActivatedEventArgs)
If args.PreviousExecutionState = ApplicationExecutionState.Terminated Then
' Do a synchronous restore
Await SuspensionManager.RestoreAsync
End If
Spannend ist der Part in dem man per Getdeferral WinRT bittet die Anwendung vom Suspending zu verschonen. Schließlich kann das speichern ja etwas länger dauern und damit wird der 5 Sekunden Zyklus unterbrochen.
Ob die Anwendung vom Suspended oder Terminated Modus kommt, spielt für das Restore der Settings natürlich eine Rolle.
Im eigentlichen VB.NET Programmcode wird auch der Suspensionmanager um einer Art Session wie in ASP.NET relevanten Infos abzulegen. So kann das ausgewählte Listenelement wieder hergestellt werden.
If SuspensionManager.SessionState.ContainsKey("SelectedScenario") Then
Dim selectedScenarioName As String =
TryCast(SuspensionManager.SessionState("SelectedScenario"), String)
startingScenario =
TryCast(Me.FindName(selectedScenarioName), ListBoxItem)
End If