Partager via


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 :

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 :

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 :

Triple capture d’écran de Mandelbrot X F

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.