Vue d’ensemble de la prise en charge asynchrone
C# 5 a introduit deux mot clé pour simplifier le programmation asynchrone : asynchrone et await. Ces mot clé vous permettent d’écrire du code simple qui utilise la bibliothèque parallèle de tâches pour exécuter des opérations longues (telles que l’accès réseau) dans un autre thread et accéder facilement aux résultats à la fin. Les dernières versions de Xamarin.iOS et Xamarin.Android prennent en charge async et await : ce document fournit des explications et un exemple d’utilisation de la nouvelle syntaxe avec Xamarin.
La prise en charge asynchrone de Xamarin repose sur la base de Mono 3.0 et met à niveau le profil d’API à partir de la version mobile de Silverlight pour être une version mobile de .NET 4.5.
Vue d’ensemble
Ce document présente la nouvelle async et attend les mot clé, puis décrit quelques exemples simples d’implémentation de méthodes asynchrones dans Xamarin.iOS et Xamarin.Android.
Pour une discussion plus complète sur les nouvelles fonctionnalités asynchrones de C# 5 (y compris un grand nombre d’exemples et différents scénarios d’utilisation), reportez-vous à l’article Programmation asynchrone.
L’exemple d’application effectue une requête web asynchrone simple (sans bloquer le thread principal), puis met à jour l’interface utilisateur avec le nombre de caractères et html téléchargés.
La prise en charge asynchrone de Xamarin repose sur la base de Mono 3.0 et met à niveau le profil d’API de la version mobile de Silverlight pour être une version mobile de .NET 4.5.
Spécifications
Les fonctionnalités C# 5 nécessitent Mono 3.0 inclus dans Xamarin.iOS 6.4 et Xamarin.Android 4.8. Vous serez invité à mettre à niveau votre mono, Xamarin.iOS, Xamarin.Android et Xamarin.Mac pour en tirer parti.
Utilisation d’async &await
async
et await
sont de nouvelles fonctionnalités de langage C# qui fonctionnent conjointement avec la bibliothèque parallèle de tâches pour faciliter l’écriture de code threadé pour effectuer des tâches de longue durée sans bloquer le thread principal de votre application.
async
Déclaration
Le async
mot clé est placé dans une déclaration de méthode (ou sur une méthode lambda ou anonyme) pour indiquer qu’il contient du code qui peut s’exécuter de manière asynchrone, c’est-à-dire ne pas bloquer le thread de l’appelant.
Une méthode marquée avec async
doit contenir au moins une expression ou une instruction await. Si aucune instruction n’est await
présente dans la méthode, elle s’exécute de façon synchrone (identique à si aucun modificateur n’a async
été présent). Cela entraîne également un avertissement du compilateur (mais pas une erreur).
Types de retour
Une méthode asynchrone doit retourner un Task
, Task<TResult>
ou void
.
Spécifiez le Task
type de retour si la méthode ne retourne aucune autre valeur.
Spécifiez Task<TResult>
si la méthode doit retourner une valeur, où TResult
est le type retourné (par exemple, un int
, par exemple).
Le void
type de retour est utilisé principalement pour les gestionnaires d’événements qui en ont besoin. Le code qui appelle des méthodes asynchrones void-retour ne peut pas await
sur le résultat.
Paramètres
Les méthodes asynchrones ne peuvent pas déclarer ou out
paramètresref
.
await
L’opérateur await peut être appliqué à une tâche à l’intérieur d’une méthode marquée comme asynchrone. Elle entraîne l’arrêt de l’exécution de la méthode à ce stade et attend la fin de la tâche.
L’utilisation d’await ne bloque pas le thread de l’appelant. Le contrôle est plutôt retourné à l’appelant. Cela signifie que le thread appelant n’est pas bloqué. Par exemple, le thread d’interface utilisateur n’est pas bloqué lors de l’attente d’une tâche.
Une fois la tâche terminée, la méthode reprend l’exécution au même point dans le code. Cela inclut le retour à l’étendue try d’un bloc try-catch-finally (le cas échéant). await ne peut pas être utilisé dans un bloc catch ou enfin.
En savoir plus sur await.
Gestion des exceptions
Les exceptions qui se produisent à l’intérieur d’une méthode asynchrone sont stockées dans la tâche et levées lorsque la tâche est await
exécutée. Ces exceptions peuvent être interceptées et gérées à l’intérieur d’un bloc try-catch.
Annulation
Les méthodes asynchrones qui prennent beaucoup de temps doivent prendre en charge l’annulation. En règle générale, l’annulation est appelée comme suit :
- Un
CancellationTokenSource
objet est créé. - L’instance
CancellationTokenSource.Token
est passée à une méthode asynchrone annulable. - L’annulation est demandée en appelant la
CancellationTokenSource.Cancel
méthode.
La tâche s’annule ensuite et reconnaît l’annulation.
Pour plus d’informations sur l’annulation, consultez Réglage de votre application Async (C#).
Exemple
Téléchargez l’exemple (pour iOS et Android) pour voir un exemple de travail et async
await
dans les applications mobiles. L’exemple de code est abordé plus en détail dans cette section.
Écriture d’une méthode asynchrone
La méthode suivante montre comment coder une async
méthode avec une await
tâche ed :
public async Task<int> DownloadHomepage()
{
var httpClient = new HttpClient(); // Xamarin supports HttpClient!
Task<string> contentsTask = httpClient.GetStringAsync("https://visualstudio.microsoft.com/xamarin"); // async method!
// await! control returns to the caller and the task continues to run on another thread
string contents = await contentsTask;
ResultEditText.Text += "DownloadHomepage method continues after async call. . . . .\n";
// After contentTask completes, you can calculate the length of the string.
int exampleInt = contents.Length;
ResultEditText.Text += "Downloaded the html and found out the length.\n\n\n";
ResultEditText.Text += contents; // just dump the entire HTML
return exampleInt; // Task<TResult> returns an object of type TResult, in this case int
}
Prenez note des points suivants :
- La déclaration de méthode inclut la
async
mot clé. - Le type de retour est
Task<int>
de sorte que le code appelant peut accéder à laint
valeur calculée dans cette méthode. - L’instruction return est
return exampleInt;
un objet entier : le fait que la méthode retourneTask<int>
fait partie des améliorations du langage.
Appel d’une méthode asynchrone 1
Ce bouton cliquez sur le gestionnaire d’événements dans l’exemple d’application Android pour appeler la méthode décrite ci-dessus :
GetButton.Click += async (sender, e) => {
Task<int> sizeTask = DownloadHomepage();
ResultTextView.Text = "loading...";
ResultEditText.Text = "loading...\n";
// await! control returns to the caller
var intResult = await sizeTask;
// when the Task<int> returns, the value is available and we can display on the UI
ResultTextView.Text = "Length: " + intResult ;
// "returns" void, since it's an event handler
};
Remarques :
- Le délégué anonyme a le préfixe mot clé asynchrone.
- La méthode asynchrone DownloadHomepage retourne un int> Task<stocké dans la variable sizeTask.
- Le code attend sur la variable sizeTask. Il s’agit de l’emplacement où la méthode est suspendue et que le contrôle est retourné au code appelant jusqu’à ce que la tâche asynchrone se termine sur son propre thread.
- L’exécution ne s’interrompt pas lorsque la tâche est créée sur la première ligne de la méthode, malgré la tâche en cours de création. L’mot clé await signifie l’emplacement où l’exécution est suspendue.
- Une fois la tâche asynchrone terminée, intResult est défini et l’exécution se poursuit sur le thread d’origine, à partir de la ligne await.
Appel d’une méthode asynchrone 2
Dans l’exemple d’application iOS, l’exemple est écrit légèrement différemment pour illustrer une autre approche. Au lieu d’utiliser un délégué anonyme, cet exemple déclare un gestionnaire d’événements async
affecté comme un gestionnaire d’événements standard :
GetButton.TouchUpInside += HandleTouchUpInside;
La méthode du gestionnaire d’événements est ensuite définie comme indiqué ici :
async void HandleTouchUpInside (object sender, EventArgs e)
{
ResultLabel.Text = "loading...";
ResultTextView.Text = "loading...\n";
// await! control returns to the caller
var intResult = await DownloadHomepage();
// when the Task<int> returns, the value is available and we can display on the UI
ResultLabel.Text = "Length: " + intResult ;
}
Quelques points importants :
- La méthode est marquée comme
async
étant mais renvoievoid
. Cela est généralement effectué uniquement pour les gestionnaires d’événements (sinon vous retourneriez uneTask
ouTask<TResult>
). - Le
await
mot clé de laDownloadHomepage
méthode affecte directement à une variable (intResult
) contrairement à l’exemple précédent où nous avons utilisé une variable intermédiaireTask<int>
pour référencer la tâche. Il s’agit de l’emplacement où le contrôle est retourné à l’appelant jusqu’à ce que la méthode asynchrone soit terminée sur un autre thread. - Lorsque la méthode asynchrone se termine et retourne, l’exécution reprend au niveau du
await
résultat entier retourné, puis rendu dans un widget d’interface utilisateur.
Résumé
L’utilisation d’async et await simplifie considérablement le code requis pour générer des opérations longues sur des threads d’arrière-plan sans bloquer le thread principal. Ils facilitent également l’accès aux résultats une fois la tâche terminée.
Ce document a donné une vue d’ensemble des nouvelles mot clé de langage et des exemples pour Xamarin.iOS et Xamarin.Android.
Liens associés
- Rappels comme l’instruction Go To de nos générations
- MapKitSearch (iOS) (exemple)
- Programmation asynchrone
- Ajuster une application Async (C#)
- Await, and UI, and deadlocks ! Oh mon Dieu !
- Traitement des tâches à mesure qu’elles se terminent)
- Modèle asynchrone basé sur les tâches (TAP, Task-based Asynchronous Pattern)
- Asynchrony en C# 5 (blog d’Eric Lippert) – à propos de l’introduction des mot clé s