Résumé du chapitre 20. E/S de fichier et asynchrone
Remarque
Ce livre a été publié au printemps 2016 et n’a pas été mis à jour depuis. Il y a beaucoup dans le livre qui reste précieux, mais certains documents sont obsolètes, et certains sujets ne sont plus entièrement corrects ou complets.
Une interface utilisateur graphique doit répondre de manière séquentielle aux événements d’entrée utilisateur. Cela implique que tout le traitement des événements d’entrée utilisateur doit se produire dans un thread unique, souvent appelé thread principal ou thread d’interface utilisateur.
Les utilisateurs s’attendent à ce que les interfaces utilisateur graphiques soient réactives. Cela signifie qu’un programme doit traiter rapidement les événements d’entrée utilisateur. Si cela n’est pas possible, le traitement doit être relégué vers des threads secondaires d’exécution.
Plusieurs exemples de programmes de ce livre ont utilisé la WebRequest
classe. Dans cette classe, la BeginGetResponse
méthode démarre un thread de travail, qui appelle une fonction de rappel lorsqu’elle est terminée. Toutefois, cette fonction de rappel s’exécute dans le thread de travail, de sorte que le programme doit appeler Device.BeginInvokeOnMainThread
la méthode pour accéder à l’interface utilisateur.
Remarque
Xamarin.Forms les programmes doivent utiliser HttpClient
plutôt que WebRequest
d’accéder aux fichiers via Internet. HttpClient
prend en charge les opérations asynchrones.
Une approche plus moderne du traitement asynchrone est disponible dans .NET et C#. Cela implique les Task
classes et Task<TResult>
les autres types dans les System.Threading
espaces de noms et System.Threading.Tasks
les espaces de noms, ainsi que les mots clés et await
C# 5.0async
. C’est ce que ce chapitre se concentre sur.
Des rappels à attendre
La Page
classe elle-même contient trois méthodes asynchrones pour afficher les zones d’alerte :
DisplayAlert
retourne unTask
objetDisplayAlert
retourne unTask<bool>
objetDisplayActionSheet
retourne unTask<string>
objet
Les Task
objets indiquent que ces méthodes implémentent le modèle asynchrone basé sur des tâches, appelé TAP. Ces Task
objets sont retournés rapidement à partir de la méthode. Les Task<T>
valeurs de retour constituent une « promesse » qu’une valeur de type TResult
sera disponible une fois la tâche terminée. La Task
valeur de retour indique une action asynchrone qui se termine, mais sans valeur retournée.
Dans tous ces cas, l’opération Task
est terminée lorsque l’utilisateur ignore la zone d’alerte.
Alerte avec rappels
L’exemple AlertCallbacks montre comment gérer les Task<bool>
objets de retour et Device.BeginInvokeOnMainThread
les appels à l’aide de méthodes de rappel.
Alerte avec lambdas
L’exemple AlertLambdas montre comment utiliser des fonctions lambda anonymes pour la gestion Task
et Device.BeginInvokeOnMainThread
les appels.
Une alerte avec await
Une approche plus simple implique les async
mots clés introduits await
en C# 5. L’exemple AlertAwait illustre leur utilisation.
Une alerte sans rien
Si la méthode asynchrone retourne Task
plutôt que Task<TResult>
, le programme n’a pas besoin d’utiliser l’une de ces techniques s’il n’a pas besoin de savoir quand la tâche asynchrone se termine. L’exemple NothingAlert illustre ceci.
Enregistrement asynchrone des paramètres du programme
L’exemple SaveProgramChanges illustre l’utilisation de la SavePropertiesAsync
méthode permettant d’enregistrer les paramètres du Application
programme au fur et à mesure qu’ils changent sans remplacer la OnSleep
méthode.
Minuteur indépendant de la plateforme
Il est possible d’utiliser Task.Delay
pour créer un minuteur indépendant de la plateforme. L’exemple TaskDelayClock illustre ceci.
Entrée/sortie de fichier
Traditionnellement, l’espace de noms .NET System.IO
a été la source de la prise en charge des E/S de fichier. Bien que certaines méthodes de cet espace de noms prennent en charge les opérations asynchrones, la plupart ne le font pas. L’espace de noms prend également en charge plusieurs appels de méthode simples qui effectuent des fonctions d’E/S de fichier sophistiquées.
Bonnes nouvelles et mauvaises nouvelles
Toutes les plateformes prises en charge par Xamarin.Forms la prise en charge du stockage local d’application ( stockage privé de l’application).
Les bibliothèques Xamarin.iOS et Xamarin.Android incluent une version de .NET que Xamarin a expressément adaptée à ces deux plateformes. Ces classes incluent des classes à partir de System.IO
laquelle vous pouvez utiliser pour effectuer des E/S de fichier avec un stockage local d’application dans ces deux plateformes.
Toutefois, si vous recherchez ces System.IO
classes dans une Xamarin.Forms bibliothèque PCL, vous ne les trouverez pas. Le problème est que Microsoft a complètement repensé les E/S de fichier pour l’API Windows Runtime. Programmes ciblant Windows 8.1, Windows Phone 8.1 et les plateforme Windows universelle ne sont pas utilisés System.IO
pour les E/S de fichier.
Cela signifie que vous devrez utiliser le DependencyService
(premièrement abordé dans le chapitre 9). Appels d’API spécifiques à la plateforme pour implémenter des E/S de fichier.
Remarque
Les bibliothèques de classes portables ont été remplacées par des bibliothèques .NET Standard 2.0, et .NET Standard 2.0 prend en charge System.IO
les types pour toutes les Xamarin.Forms plateformes. Il n’est plus nécessaire d’utiliser une DependencyService
pour la plupart des tâches d’E/S de fichier. Consultez la gestion des fichiers pour Xamarin.Forms une approche plus moderne des E/S de fichiers.
Un premier coup d’E/S entre les fichiers multiplateformes
L’exemple TextFileTryout définit une IFileHelper
interface pour les E/S de fichier et les implémentations de cette interface dans toutes les plateformes. Toutefois, les implémentations Windows Runtime ne fonctionnent pas avec les méthodes de cette interface, car les méthodes d’E/S du fichier Windows Runtime sont asynchrones.
Prise en charge des E/S de fichier Windows Runtime
Les programmes exécutés sous Windows Runtime utilisent des classes dans les espaces de noms et Windows.Storage.Streams
les Windows.Storage
E/S de fichier, y compris le stockage local de l’application. Étant donné que Microsoft a déterminé que toute opération nécessitant plus de 50 millisecondes doit être asynchrone pour éviter de bloquer le thread d’interface utilisateur, ces méthodes d’E/S de fichier sont principalement asynchrones.
Le code illustrant cette nouvelle approche se trouve dans une bibliothèque afin qu’elle puisse être utilisée par d’autres applications.
Bibliothèques propres à une plateforme
Il est avantageux de stocker du code réutilisable dans les bibliothèques. Cela est évidemment plus difficile lorsque différents éléments du code réutilisable sont destinés à des systèmes d’exploitation entièrement différents.
La Xamarin.Formssolution Book.Platform illustre une approche. Cette solution contient sept projets différents :
- Xamarin.FormsBook.Platform, une bibliothèque PCL normale Xamarin.Forms
- Xamarin.FormsBook.Platform.iOS, une bibliothèque de classes iOS
- Xamarin.FormsBook.Platform.Android, une bibliothèque de classes Android
- Xamarin.FormsBook.Platform.UWP, bibliothèque de classes Windows universelle
- Xamarin.FormsBook.Platform.WinRT, un projet partagé pour le code commun à toutes les plateformes Windows
Tous les projets de plateforme individuels (à l’exception de Book.Platform.WinRT) ont des références à Xamarin.FormsBook.Platform.Xamarin.Forms Les trois projets Windows ont une référence à Xamarin.FormsBook.Platform.WinRT.
Tous les projets contiennent une méthode statique Toolkit.Init
pour s’assurer que la bibliothèque est chargée si elle n’est pas directement référencée par un projet dans une solution d’application Xamarin.Forms .
Le Xamarin.Formsprojet Book.Platform contient la nouvelle IFileHelper
interface. Toutes les méthodes ont désormais des noms avec Async
des suffixes et des objets de retour Task
.
Le Xamarin.Formsprojet Book.Platform.WinRT contient la FileHelper
classe pour Windows Runtime.
Le Xamarin.Formsprojet Book.Platform.iOS contient la FileHelper
classe pour iOS. Ces méthodes doivent maintenant être asynchrones. Certaines des méthodes utilisent les versions asynchrones des méthodes définies dans StreamWriter
et StreamReader
: WriteAsync
et ReadToEndAsync
. D’autres convertissent un résultat en objet Task
à l’aide de la FromResult
méthode.
Le Xamarin.Formsprojet Book.Platform.Android contient une classe similaire FileHelper
pour Android.
Le Xamarin.Formsprojet Book.Platform contient également une FileHelper
classe qui facilite l’utilisation de l’objet DependencyService
.
Pour utiliser ces bibliothèques, une solution d’application doit inclure tous les projets de la Xamarin.Formssolution Book.Platform , et chacun des projets d’application doit avoir une référence à la bibliothèque correspondante dans Xamarin.FormsBook.Platform.
La solution TextFileAsync montre comment utiliser les Xamarin.Formsbibliothèques Book.Platform. Chacun des projets a un appel à Toolkit.Init
. L’application utilise les fonctions d’E/S de fichier asynchrones.
Maintien en arrière-plan
Les méthodes des bibliothèques qui effectuent des appels à plusieurs méthodes asynchrones, telles que les méthodes et ReadFileASync
les WriteFileAsync
méthodes de la classe Windows RuntimeFileHelper
, peuvent être effectuées un peu plus efficacement à l’aide de la ConfigureAwait
méthode pour éviter de revenir au thread d’interface utilisateur.
Ne bloquez pas le thread d’interface utilisateur !
Parfois, il est tentant d’éviter l’utilisation ou await
l’utilisation de ContinueWith
la Result
propriété sur les méthodes. Cela doit être évité pour qu’il puisse bloquer le thread d’interface utilisateur ou même bloquer l’application.
Vos propres méthodes awaitables
Vous pouvez exécuter du code de façon asynchrone en le Task.Run
transmettant à l’une des méthodes. Vous pouvez appeler Task.Run
dans une méthode asynchrone qui gère une partie de la surcharge.
Les différents Task.Run
modèles sont abordés ci-dessous.
Jeu de base De Mandelbrot
Pour dessiner le Jeu de Mandelbrot en temps réel, le Xamarin.Forms. La bibliothèque toolkit a une Complex
structure similaire à celle de l’espace System.Numerics
de noms.
L’exemple MandelbrotSet a une CalculateMandeblotAsync
méthode dans son fichier code-behind qui calcule l’ensemble de base de données black-and-white Mandelbrot et l’utilise BmpMaker
pour le placer sur une bitmap.
Progression du marquage
Pour signaler la progression d’une méthode asynchrone, vous pouvez instancier une Progress<T>
classe et définir votre méthode asynchrone pour avoir un argument de type IProgress<T>
. Ceci est illustré dans l’exemple De MandbrotProgress .
Annulation du travail
Vous pouvez également écrire une méthode asynchrone pour être annulable. Vous commencez par une classe nommée CancellationTokenSource
. La Token
propriété est une valeur de type CancellationToken
. Ceci est passé à la fonction asynchrone. Un programme appelle la Cancel
méthode de CancellationTokenSource
(généralement en réponse à une action de l’utilisateur) pour annuler la fonction asynchrone.
La méthode asynchrone peut vérifier régulièrement la IsCancellationRequested
propriété de CancellationToken
la propriété et la quitter si la propriété est true
, ou simplement appeler la ThrowIfCancellationRequested
méthode, auquel cas la méthode se termine par un OperationCancelledException
.
L’exemple De VariablebrotCancellation illustre l’utilisation d’une fonction annulable.
Un MVVM Mandelbrot
L’exemple MandelbrotXF dispose d’une interface utilisateur plus étendue, et il est principalement basé sur une MandelbrotModel
et MandelbrotViewModel
des classes :
Retour sur le web
La WebRequest
classe utilisée dans certains exemples utilise un protocole asynchrone de mode ancien appelé modèle de programmation asynchrone ou APM. Vous pouvez convertir une telle classe en protocole TAP moderne à l’aide de l’une FromAsync
des méthodes de la TaskFactory
classe. L’exemple ApmToTap illustre ceci.