Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Sviluppare Metro-style app per Windows 8 con Visual Basic - settima parte

Dopo aver parlato dell'orientamento e dello snap nella parte precedente, è ora di passare ad alcune considerazioni sul ciclo di vita dell'applicazione, in particolare la sospensione e il ripristino del funzionamento.

Sospensione e ripristino delle app

Non voglio fare considerazioni avanzate a livello architetturale, anche perché ci sono altri ben più preparati di me sulla cosa, ma piuttosto fare delle considerazioni da un punto di vista più pratico. Quando avete a che fare con un'app Metro e poi passate ad un'altra app oppure passate al desktop oppure fate qualunque altra cosa, l'app precedentemente aperta non viene effettivamente chiusa ma viene messa da parte e la sua esecuzione viene sospesa.

Le ragioni per questa sospensione stanno prevalentemente nel ridurre il consumo di risorse di sistema e, conseguentemente, anche di quello energetico (cosa importante sui device). Questo comporta che dobbiamo prevedere cosa succede quando un'app viene sospesa dal sistema e come ripristinare le informazioni che erano in corso di uso o elaborazione, nel momento in cui l'app viene riportata in primo piano. Tecnicamente gestire la sospensione è un plus, perché mal che vada l'app viene rieseguita da zero.

La classe App offre un evento chiamato OnSuspending che può essere gestito per salvare lo stato dell'applicazione nel momento in cui il sistema la sta sospendendo. Tenuto conto del fatto che questa implementazione deve essere per forza di cose fatta in modalità asincrona e tenuto conto del fatto che probabilmente a questo punto non abbiamo la minima idea di come fare, ecco che ci viene in aiuto l'SDK con gli esempi di codice per Windows 8 disponibili sulla Code Gallery di MSDN.

Gestire la sospensione e la ripresa da codice

Ognuno degli esempi dell'SDK include un modulo chiamato SuspensionManager.vb. Questo modulo, a un livello più alto, espone due metodi chiamati SaveAsync e RestoreAsync che permettono rispettivamente di salvare e ripristinare lo stato di un'applicazione.

E' quindi buona cosa aggiungere un modulo con lo stesso nome anche nel progetto che stiamo portando avanti in questa serie di post. Il codice del modulo è stato interamente ripreso dalla Code Gallery e i commenti all'interno del codice aiuteranno a capirne l'implementazione:

Imports System.IO
Imports System.Runtime.Serialization
Imports Windows.Storage
Imports Windows.Storage.Streams
 
Module SuspensionManager
    Private sessionState_ As New Dictionary(Of StringObject)
    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 StringObject)
        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 StringObject)))
            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 StringObject)))
            sessionState_ = CType(serializer.ReadObject(inStream.AsStreamForRead), Dictionary(Of StringObject)) 
        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

Una volta implementato questo modulo, utilizzarne i due metodi è davvero semplice. Il tutto avviene nel file App.xaml.vb. Nel gestore di evento OnSuspending richiamiamo il SaveAsync:

    ''' <summary>
    ''' Invoked when application execution is being suspended.  Application state is saved
    ''' without knowing whether the application will be terminated or resumed with the contents
    ''' of memory still intact.
    ''' </summary>
    ''' <param name="sender">The source of the suspend request.</param>
    ''' <param name="e">Details about the suspend request.</param>
    Protected Async Sub OnSuspending(sender As Object, e As SuspendingEventArgs) Handles Me.Suspending
        Dim deferral As SuspendingDeferral = e.SuspendingOperation.GetDeferral
        Await SuspensionManager.SaveAsync
        deferral.Complete()
    End Sub

Poi riscriviamo il gestore OnLaunched, che viene invocato sia al "risveglio" dell'app sia al caricamento di un'istanza nuova:

    ''' <summary>
    ''' Invoked when the application is launched normally by the end user.  Other entry points
    ''' will be used when the application is launched to open a specific file, to display
    ''' search results, and so forth.
    ''' </summary>
    ''' <param name="args">Details about the launch request and process.</param>
    Protected Overrides Async Sub OnLaunched(args As Windows.ApplicationModel.Activation.LaunchActivatedEventArgs)
        If args.PreviousExecutionState = ApplicationExecutionState.Terminated Then
            Await SuspensionManager.RestoreAsync
        End If
 
    ' Create a Frame to act navigation context and navigate to the first page
        Dim rootFrame As New Frame()
        rootFrame.Navigate(GetType(BlankPage))
 
    ' Place the frame in the current Window and ensure that it is active
        Window.Current.Content = rootFrame
        Window.Current.Activate()
    End Sub

Il primo snippet va a ripristinare lo stato dell'applicazione. Si tratta sicuramente di rendere la nostra app più efficiente con degli accorgimenti importanti, per giunta già disponibili nell'SDK. E' chiaro che questa è un'implementazione standard e non sempre sarà perfetta per tutte le app, ma ci aiuta a capire come muoverci.

Il Task Manager di Windows 8

In realtà non è proprio strettamente correlato al post di oggi, però sempre a proposito di efficienza e performance, il Task Manager di Windows 8 ha un'apposita scheda chiamata App History che riassume l'utilizzo di risorse in termini di CPU e rete da parte delle app:

La prossima volta vedremo come aggiungere la ricerca integrata con Windows. Per ora potete scaricare il codice aggiornato da questo indirizzo.

Alessandro

Print | posted on venerdì 18 maggio 2012 17:31 | Filed Under [ Visual Basic UWP e Windows Store Apps Visual Studio 2012 ]

Powered by:
Powered By Subtext Powered By ASP.NET