opérateur await : attend de façon asynchrone la fin d’une tâche
L’opérateur await
suspend l’évaluation de la méthode async englobante jusqu’à ce que l’opération asynchrone représentée par son opérande se termine. Une fois l’opération asynchrone terminée, l’opérateur await
retourne le résultat de l’opération, le cas échéant. Quand l’opérateur await
est appliqué à l’opérande qui représente une opération déjà terminée, il retourne immédiatement le résultat de l’opération sans suspendre la méthode englobante. L’opérateur await
ne bloque pas le thread qui évalue la méthode async. Quand l’opérateur await
suspend la méthode englobante, le contrôle retourne à l’appelant de la méthode.
Dans l’exemple suivant, la méthode HttpClient.GetByteArrayAsync retourne l’instance Task<byte[]>
, qui représente une opération asynchrone qui produit un tableau d’octets au moment où elle se termine. Tant que l’opération n’est pas terminée, l’opérateur await
suspend la méthode DownloadDocsMainPageAsync
. Quand la méthode DownloadDocsMainPageAsync
est suspendue, le contrôle est retourné à la méthode Main
, qui est l’appelant de DownloadDocsMainPageAsync
. La méthode Main
s’exécute jusqu’à ce qu’elle ait besoin du résultat de l’opération asynchrone effectuée par la méthode DownloadDocsMainPageAsync
. Une fois que tous les octets ont été obtenus par GetByteArrayAsync, le reste de la méthode DownloadDocsMainPageAsync
est évalué. Après cela, le reste de la méthode Main
est évalué.
public class AwaitOperator
{
public static async Task Main()
{
Task<int> downloading = DownloadDocsMainPageAsync();
Console.WriteLine($"{nameof(Main)}: Launched downloading.");
int bytesLoaded = await downloading;
Console.WriteLine($"{nameof(Main)}: Downloaded {bytesLoaded} bytes.");
}
private static async Task<int> DownloadDocsMainPageAsync()
{
Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: About to start downloading.");
var client = new HttpClient();
byte[] content = await client.GetByteArrayAsync("https://learn.microsoft.com/en-us/");
Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");
return content.Length;
}
}
// Output similar to:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.
L’opérande d’une expression await
doit fournir une notification lorsqu’une tâche se termine. En général, un délégué est appelé lorsque la tâche se termine, que ce soit une réussite ou un échec. La section await
de la spécification du langage C# fournit les détails sur la façon dont ces notifications sont implémentées.
L’exemple précédent utilise la méthode méthode Main
asynchrone. Pour plus d’informations, consultez la section Opérateur await dans la méthode Main.
Notes
Pour obtenir une introduction à la programmation asynchrone, consultez Programmation asynchrone avec async et await. La programmation asynchrone avec async
et await
suit le modèle asynchrone basé sur les tâches.
Vous pouvez utiliser l’opérateur await
uniquement dans une méthode, une expression lambda ou une méthode anonyme modifiée par le mot clé async. Dans une méthode asynchrone, vous ne pouvez pas utiliser l’opérateur await
dans le corps d’une fonction synchrone, à l’intérieur du bloc d’une instruction lock et dans un contexte non managé.
L’opérande de l’opérateur await
est généralement un des types .NET suivants : Task, Task<TResult>, ValueTask ou ValueTask<TResult>. Cependant, n’importe quelle expression awaitable peut être l’opérande de l’opérateur await
. Pour plus d’informations, consultez la section Expressions awaitable de la spécification du langage C#.
Le type d’expression await t
est TResult
si le type d’expression t
est Task<TResult> ou ValueTask<TResult>. Si le type de t
est Task ou ValueTask, le type de await t
est void
. Dans les deux cas, si t
lève une exception, await t
lève à nouveau l’exception.
Flux asynchrones et éléments jetables
Vous utilisez l’instruction await foreach
pour consommer un flux asynchrone de données. Pour plus d’informations, consultez la section foreach
de l’article Instructions d’itération.
Vous utilisez l’instruction await using
pour utiliser un objet jetable de façon asynchrone. Autrement dit un objet d’un type qui implémente une interface IAsyncDisposable. Pour plus d’informations, consultez la section Utilisation d’objet jetable asynchrone de l’article Implémenter une méthode DisposeAsync.
Opérateur await dans la méthode Main
La méthode Main
, qui est le point d’entrée de l’application, peut retourner Task
ou Task<int>
, ce qui lui permet d’être asynchrone. Vous pouvez ainsi utiliser l’opérateur await
dans son corps. Dans les versions antérieures de C#, pour être certain que la méthode Main
attend la fin d’une opération asynchrone, vous pouvez récupérer la valeur de la propriété Task<TResult>.Result de l’instance Task<TResult> retournée par la méthode asyn correspondante. Pour les opérations asynchrones qui ne produisent pas de valeur, vous pouvez appeler la méthode Task.Wait. Pour savoir comment sélectionner la version du langage, voir Contrôle de version du langage C#.
spécification du langage C#
Pour plus d’informations, consultez la section Expressions await de la spécification du langage C#.