Isolated Storage et Images sous Windows Phone 8


Je vous propose un petit tour d’horizon sur le stockage d’images dans l’Isolated Storage.

Pour rappel, l’Isolated storage est l’emplacement réservé à votre application Windows Phone pour le stockage de fichiers.

Quelles sont les implémentations qui permettent de récupérer une image déjà stockée dans cet espace ? Quelles sont les méthodes les plus efficaces ?

L’implémentation classique (Windows Phone 7)

C’est l’implémentation standard « old school » : j’utilise GetUserStoreForApplication() et OpenFile pour lire un Stream. Le Stream est ensuite lu par le BitmapImage et renvoyé dans une Action.

Remarque 1

BitmapImage nécessite de s’exécuter dans le ThreadUI principal, pour cela, on utilise

Remarque 2

Le Stream de l’isolated Storage peut s’exécuter dans un Thread en arrière plan, on ne peut pas ici utiliser une syntaxe comme celle ci dessous (qui permettrait de garantir la libération mémoire du FileStream).

Attention donc, car l’utilisation du using fermerait le FileStream avant que le ThreadUI ne puisse l’utiliser.

Utilisation de la méthode

L’utilisation de cette première méthode pourrait être celle ci :

(où image représente une propriété de type BitmapImage)

 

L’implémentation Windows Phone 8 (async / await)

Windows Phone 8 permet l’ancienne syntaxe Windows Phone 7, mais ajoute également tout une gestion de l’Isolated Storage avec la nouvelle classe StorageFile.

La classe StorageFile va proposer des actions asynchrones assez efficaces.

Ici, j’utilise GetFileFromApplicationUriAsync pour récupérer en une seule instruction le fichier image de l’Isolated Storage.

Le Stream est ensuite accessible avec OpenStreamForReadAsync();

Remarque 1

Le code suivant :

permet d’utiliser l’UIThread principal, obligatoire pour l’utilisation de BitmapImage. Il peut être remplacé par

Remarque 2

L’utilisation du MemoryStream permet d’éviter une fuite mémoire qui a lieu lorsque le Stream de l’IsolatedStorage reste bloqué dans le Thread de tâche de fond.

C’est le flux de données copié dans le MemoryStream qui va ensuite être utilisé par le BitmapImage.

Remarque 3

Il est possible d’utiliser la syntaxe Using sur les Stream sans générer de fuites mémoire:

Appel de la méthode

La méthode peut alors être appelée de la façon suivante  :

(où Image est une propriété de type BitmapImage)

Une autre implementation async await Windows Phone 8

Il existe une variante du code précédent avec l’utilisation d’un IRandomAccessStream et du ReadAsync.

Le ReadAsync lit les données dans un buffer et utilise un MemoryStream pour son injection dans BitmapImage.

Quelle méthode est la plus rapide ?

J’ai repris le programme de Benchmark et testé nos 3 méthodes en chargeant une image importante (400ko, 1000 pixels x 1000 pixels) 100 fois.

Benchmark Screenshot

Voici les résultats (moyennes après une dizaine de tests consécutifs pour 100 appels):

  • Méthode 1 (Action, syntaxe wp7 ) : 8,5 secondes
  • Méthode 2 (WP8 avec GetFileFromApplicationUriAsync : 11 secondes
  • Méthode 3 (WP8 avec IRandomAccessStream et ReadAsync : 9,5 secondes

Avec ce test, on voit que l’utilisation de IRandomAccessStream avec Async / Await  n’est pas très éloignée d’une utilisation avec le simple Action.

Les 3 méthodes restent cependant incroyablement longues par rapport à l’utilisation directe d’une ressource de l’application.(0,3 s).

Conclusion : Privilégiez toujours l’utilisation des ressources lorsque c’est possible.

Le code source est ici :

download-10-icon-256

 

 

Laissez un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

2 + 8 =