Share via


Ottimizzare la sospensione e la ripresa

Crea app UWP che semplificano l’uso del sistema Gestione del ciclo di vita dei processi per una ripresa più efficiente dopo la sospensione o la terminazione.

Launch

Al momento della riattivazione di un'app dopo la sospensione o la terminazione, verifica se è trascorso molto tempo. In tal caso, valuta la possibilità di tornare alla pagina di destinazione principale dell'app anziché visualizzare i dati dell'utente non aggiornati. Ciò consentirà anche un avvio più rapido.

Durante l'attivazione, controlla sempre il valore di PreviousExecutionState del parametro degli argomenti dell'evento (ad esempio, per le attivazioni avviate controlla LaunchActivatedEventArgs.PreviousExecutionState). Se il valore è ClosedByUser o NotRunning, non sprecare tempo a ripristinare lo stato salvato in precedenza. In questo caso, la scelta giusta consiste nel fornire un'esperienza nuova e il risultato sarà anche un avvio più rapido.

Invece di ripristinare ripetutamente lo stato salvato in precedenza, valuta la possibilità di tenere traccia di tale stato e ripristinarlo solo su richiesta. Considera ad esempio una situazione in cui l'app è stata sospesa in precedenza, ha salvato lo stato per 3 pagine e quindi è stata terminata. Al riavvio, se decidi di riportare l'utente alla pagina 3, non occorre ripristinare lo stato per le prime 2 pagine. Tieni invece traccia di questo stato e usalo solo quando sai che ti serve.

Durante l'esecuzione

Come procedura consigliata, non attendere l'evento di sospensione per poi salvare in modo permanente una grande quantità di stato. Al contrario, l'applicazione dovrebbe rendere persistenti in modo incrementale piccole quantità di stato durante l'esecuzione. Questo è particolarmente importante per le app più grandi che rischiano di esaurire il tempo durante la sospensione se tentano di salvare tutto in una volta.

Tuttavia, dovrai trovare il giusto equilibrio tra salvataggio incrementale e le prestazioni della tua app durante l'esecuzione. Un buon compromesso consiste nel tenere traccia in modo incrementale dei dati modificati (che quindi devono essere salvati) e poi usare l'evento di sospensione per salvare effettivamente i dati (processo più veloce rispetto al salvataggio di tutti i dati o all'esame dell'intero stato dell'app per decidere cosa salvare).

Non usare gli eventi Activated o VisibilityChanged della finestra per decidere quando salvare lo stato. Quando l'utente esce dalla tua app, la finestra viene disattivata, ma il sistema attende un breve intervallo di tempo (circa 10 secondi) prima di sospenderla. Lo scopo è quello di offrire un'esperienza più reattiva nel caso in cui l'utente decida di tornare velocemente alla tua app. Aspetta l'evento di sospensione prima di eseguire la logica di sospensione.

Sospendi

Durante la sospensione, riduci il footprint della tua app. Se l'app usa meno memoria durante la sospensione, il sistema generale sarà più reattivo e verranno terminate meno app sospese (inclusa la tua). Tuttavia, sarà necessario trovare un equilibro tra questo aspetto e la necessità di gestire efficacemente le riprese: non ridurre il footprint al punto di rallentare notevolmente la ripresa mentre l'app ricarica grandi quantità di dati in memoria.

Per le app gestite, il sistema eseguirà un passaggio di Garbage Collection dopo il completamento dei gestori della sospensione dell'app. Assicurati di sfruttare questo aspetto rilasciando i riferimenti agli oggetti che ti aiuteranno a ridurre il footprint dell'app mentre è sospesa.

Idealmente, l'app dovrà completare la logica di sospensione in meno di 1 secondo. La soluzione ottimale consiste nel gestire il più velocemente possibile la sospensione. Ciò renderà possibile un'esperienza utente più dinamica per le altre app e parti del sistema. Se necessario, la logica di sospensione può richiedere fino a 5 secondi in dispositivi desktop o 10 secondi nei dispositivi mobili. In caso di superamento di questi tempi, l'app verrà terminata bruscamente. Vorrai evitare che ciò accada, perché in questo caso, quando l'utente torna alla tua app viene avviato nuovo processo e l'esperienza risulterà molto più lenta rispetto alla ripresa di un'app sospesa.

Riprendi

La maggior parte delle app non deve eseguire operazioni particolari al momento della ripresa, quindi, in genere non dovrai gestire questo evento. Alcune app usano la ripresa per ripristinare le connessioni chiuse durante la sospensione o per aggiornare i dati. Invece di eseguire queste operazioni a prescindere, progetta la tua app in modo che possa avviare queste attività su richiesta. Il risultato sarà un'esperienza più veloce quando l'utente torna a un'app sospesa e potrai così assicurarti di eseguire solo il lavoro effettivamente necessario per l'utente.

Evitare le interruzioni non necessarie

Il sistema Gestione del ciclo di vita dei processi della piattaforma UWP può sospendere o terminare un'app per molti motivi diversi. Questo processo è progettato per riportare rapidamente un'app allo stato in cui si trovava prima che fosse sospesa o terminata. Quando il processo funziona bene, l'utente non si accorge neanche che l'app ha subito un'interruzione. Ecco alcuni suggerimenti da usare nella tua app UWP per semplificare le transizioni del sistema durante il ciclo di vita dell'app.

Un'app può essere sospesa quando l'utente la sposta in secondo piano o quando il sistema entra in modalità basso consumo. Quando sta per essere sospesa, l'app genera l'evento di sospensione e ha a disposizione 5 secondi di tempo per salvare i dati. Se il gestore dell'evento di sospensione dell'app non completa l'operazione entro 5 secondi, il sistema presuppone che l'app abbia smesso di rispondere e la interrompe. Un'app terminata deve ripetere il lungo processo di avvio invece di essere immediatamente caricata in memoria quando un utente passa ad essa.

Serializzare solo quando necessario

Molte app serializzano tutti i loro dati in fase di sospensione. Se hai necessità di archiviare una piccola quantità di dati delle impostazioni dell’app, usa l’archivio LocalSettings invece di serializzare i dati. Ricorri alla serializzazione per quantità maggiori di dati e per quelli non correlati alle impostazioni.

Se scegli di eseguire la serializzazione, evita di riserializzare i dati se non sono stati modificati. La serializzazione e il salvataggio dei dati richiedono tempo, così come la lettura e la deserializzazione quando l'app viene riattivata. Piuttosto, fai in modo che sia l'app a determinare se il suo stato è cambiato e, se sì, proceda alla serializzazione e deserializzazione dei soli dati cambiati. Un buon modo per far sì che questo accada consiste nel serializzare periodicamente i dati in background quando vengono modificati. Con questa tecnica, tutto ciò che deve essere serializzato alla sospensione è già stato salvato, quindi non c'è altro da fare e l'app viene sospesa rapidamente.

Serializzazione dei dati in C# e Visual Basic

Le tecnologie di serializzazione disponibili per le app .NET sono le classi System.Xml.Serialization.XmlSerializer, System.Runtime.Serialization.DataContractSerializer e System.Runtime.Serialization.Json.DataContractJsonSerializer.

Dal punto di vista delle prestazioni, ti consigliamo di usare la classe XmlSerializer. La classe XmlSerializer vanta i tempi di serializzazione e deserializzazione più brevi e mantiene basso il footprint di memoria. XmlSerializer ha poche dipendenze da .NET Framework e di conseguenza, rispetto alle altre tecnologie di serializzazione, nell’app deve essere caricato un numero minore di moduli per usare XmlSerializer.

DataContractSerializer semplifica la serializzazione delle classi personalizzate, sebbene abbia un più considerevole impatto sulle prestazioni rispetto a XmlSerializer. Se richiedi prestazioni migliori, considera la transizione. In generale, non caricare più di un serializzatore e usa di preferenza XmlSerializer a meno che tu non richieda le funzionalità di un altro serializzatore.

Ridurre il footprint di memoria

Il sistema tende a mantenere in memoria il maggior numero possibile di app sospese, così da permettere agli utenti di passare da un'app all'altra in modo veloce e affidabile. Quando un'app è sospesa ed è nella memoria del sistema, può essere riportata rapidamente in primo piano per consentire l'interazione con l'utente, senza che sia necessario visualizzare una schermata iniziale o eseguire una lunga operazione di caricamento. Se non ci sono risorse sufficienti per mantenere un'app in memoria, l'app viene terminata. Questo comportamento rende la gestione della memoria importante per due motivi:

  • Liberando la maggior quantità di memoria possibile al momento della sospensione si riducono al minimo le probabilità che l'app venga terminata a causa della mancanza di risorse durante la sospensione.
  • Riducendo la quantità globale di memoria usata dall'app si riducono le probabilità che altre app vengano terminate durante la sospensione.

Rilasciare risorse

Alcuni oggetti, ad esempio file e dispositivi, occupano una quantità consistente di memoria. Durante la sospensione, un'app dovrebbe rilasciare gli handle a questi oggetti e ricrearli solo all'occorrenza. È una buona idea anche ripulire le cache che non saranno valide alla ripresa dell'app. Un'altra operazione che il framework XAML esegue al posto tuo per le app in C# e Visual Basic è l'esecuzione di Garbage Collection, se necessario. Questa funzionalità assicura che gli oggetti a cui il codice dell'app non fa più riferimento vengano rilasciati.

Ripresa rapida

Un'app sospesa si riprende, ad esempio, quando l'utente la sposta in primo piano o quando il sistema entra nella modalità basso consumo. Quando un'app esce dallo stato di sospensione, riprende la propria attività dal punto in cui era stata sospesa. Nessun dato dell'app va perduto, perché tutti i dati sono stati archiviati in memoria, anche se l'app è stata sospesa per un lungo periodo di tempo.

La maggior parte delle app non ha bisogno di gestire l’evento Resuming. Alla ripresa dell'app, le variabili e gli oggetti si trovano nello stesso stato in cui si trovavano prima della sospensione. Gestisci l’evento Resuming solo se devi aggiornare dati o oggetti che possono avere subito modifiche tra il momento della sospensione e il momento della ripresa dell’app, ad esempio contenuti come dati di feed aggiornati, connessioni di rete obsolete, oppure se devi riacquisire l’accesso a un dispositivo, ad esempio una webcam.