Dall'archivio articoli > WinRT 8.1
Ottimizzare le prestazioni delle applicazioni WinRT e XAML
Per poter utilizzare questa funzionalità, devi fare il login o iscriverti.
Al giorno d'oggi, scrivere le applicazioni è diventato molto semplice. Con il supporto alle Universal App, poi, è addirittura possibile scrivere una sola volta la logica per produrre una applicazione per Windows ed una per Windows Phone.
Quello che manca davvero oggi è riuscire a scrivere le applicazioni che siano anche veloci e reattive: le applicazioni Windows e Windows Phone sono basate su terminali che hanno quantità di memoria e velocità di processori totalmente differenti e, soprattutto su uno smartphone che ha una memoria molto limitata, saper gestire le performance è importante.
In questo articolo, vedremo le principali problematiche che gli sviluppatori di applicazioni sono costretti ad affrontare ogni giorno, offrendo soluzioni più o meno semplici e più o meno 'reali' (vedremo più avanti cosa si intende), dando spazio sia a Windows che a Windows Phone.
Le Universal App basate su WinRT che usano C++, C# o Visual Basic sono applicazioni basate su eventi e tutti i componenti della UI condividono lo stesso thread di esecuzione. Basate su eventi significa che il codice viene eseguito in risposta di un evento. Dopo di che l'applicazione si mette in attesa, aspettando un nuovo evento. Visto che un thread può eseguire una sola operazione per volta, la durata di questa risulta determinante per la responsività della nostra applicazione.
Non tutti i cambiamenti della UI vengono necessariamente eseguiti sul thread della UI. C'è un thread separato dedicato alla responsività: è ad esempio, il thread che si incarica di gestire le animazioni o le transizioni.
Se il nostro codice interagisce con elementi della UI, è meglio assumere che il nostro codice potrà bloccare il thread della UI. Per questo motivo, per tenere le app responsiva, in WinRT i metodi che durano più di tre millisecondi sono asincroni così. Quando chiamiamo una API dal thread della UI, è quindi sempre consigliato usare API asincrone.
Ci sono casi in cui il tempo di esecuzione è molto più lungo del normale. In questo caso, è bene creare un nuovo thread ed eseguire il carico di lavoro in background.
Si può schedulare un lavoro asincronicamente usando l'operatore await (C#), Await (VB), o i delegates (C++), ma questo non garantisce che il lavoro verrà eseguito in un thread separato. Molte delle API del WinRT impostano il lavoro su un background thread al posto nostro, ma se lo facciamo noi dobbiamo usare Task.Run.
Nell'esempio seguente, tramite Task.Run viene eseguita la funzione ComputeNextMove che calcola la migliore mossa possibile per muovere la pedina del computer tra milioni di possibilità. E' una funzione molto onerosa dal punto di vista computazionale e temporale, quindi è bene eseguire il tutto in un background thread per non bloccare la UI.
public class Example { private async void NextMove_Click(object sender, RoutedEventArgs e) { await Task.Run(() => ComputeNextMove()); // Aggiorniamo l'UI } private async Task ComputeNextMove() { // codice con l'algoritmo } }
Con l'operatore await di C#, la funzione NextMove_Click aspetterà il termine della ComputeNextMove per aggiornare la UI, sempre secondo un pattern asincrono non bloccante.
Il caricamento dell XAML, per quanto compilato nativamente, è una delle cose più pesanti a livello di performance. Per ogni pagina, è consigliato l'imitare la complessità del Visual Tree: se infatti abbiamo una risorsa all'interno della pagina definita in una pagina differente, il motore dello XAML deve andare ad analizzare tutta la nuova pagina in cerca della risorsa, facendo perdere del tempo prezioso che potrebbe essere speso per calcoli più complessi o tempi di avvio più rapidi.
Se si usa una risorsa all'interno di più pagine, o magari in tutta l'applicazione, allora ha senso conservare quella risorsa in un file, per accederci ovunque ed evitare duplicazioni per dichiarazioni della stessa risorsa, risparmiando ulteriormente sul tempo di parsing.
Se invece la risorsa è specifica di una sola pagina, non ha senso dichiararla all'interno di un file globale contenente molte altre risorse condivise, poiché lo XAML dovrà analizzare tutto questo file.
<Page ...> <Page.Resources> <SolidColorBrush x:Key="TextColor" Color="#FF3F42CC"/> </Page.Resources> <StackPanel> <Button Content="Submit" Foreground="{StaticResource TextColor}" /> </StackPanel> </Page>
Come detto prima, il Visual Tree può essere molto complesso e lo sviluppatore può scegliere di comporre gli oggetti in una infinità di modi. Per velocizzare il render della pagina, è bene comporre appositamente la pagina, riducendo quando possibile il numero di elementi da mostrare.
<Grid> <Rectangle Fill="Black" /> </Grid>
<Grid Background="Black" />
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.