Partager via


Résoudre les erreurs et les avertissements dans les méthodes asynchrones à l’aide de l’opérateur Await

Cet article traite des erreurs suivantes du compilateur :

  • CS1983 : Étant donné qu’il s’agit d’une méthode asynchrone, l’expression de retour doit être de type «Task<T> » plutôt que «T ».
  • CS1985 : Impossible d'utiliser 'await' dans un bloc catch.
  • CS1986 : 'await' exige que le type ait une méthode 'GetAwaiter' appropriée.
  • CS1989 : Les expressions lambda asynchrones ne peuvent pas être converties en arborescences d’expressions.
  • CS1991 : « Type » ne peut pas implémenter « événement », car il s’agit d’un événement Windows Runtime et « événement » est un événement .NET standard.
  • CS1992 : L’opérateur 'await' ne peut être utilisé que lorsqu’il est contenu dans une méthode ou une expression lambda marquée avec le modificateur 'async'.
  • CS1994 : Le modificateur 'async' ne peut être utilisé que dans les méthodes qui ont un corps.
  • CS1995 : L’opérateur 'await' peut uniquement être utilisé dans une expression de requête dans la première expression de collection de la clause 'from' initiale ou dans l’expression de collection d’une clause 'join' .
  • CS1996 : Impossible d’attendre dans le corps d’une instruction de verrouillage.
  • CS1997 : Étant donné que la fonction est une méthode asynchrone qui retourne une valeur, un mot clé de retour ne doit pas être suivi d’une expression d’objet.
  • CS1998 : cette méthode asynchrone n’a pas d’opérateurs «await » et s’exécute de manière synchrone. Envisagez d’utiliser l’opérateur «await » pour attendre des appels d’API non bloquants, ou «await Task.Run(...) pour effectuer un travail lié au processeur sur un thread d’arrière-plan.
  • CS4008 : Impossible d’attendre 'void'.
  • CS4009 : un point d’entrée vide ou int ne peut pas être asynchrone.
  • CS4014 : Étant donné que cet appel n’est pas attendu, l’exécution de la méthode actuelle se poursuit avant la fin de l’appel. Envisagez d’appliquer l’opérateur await au résultat de l’appel.
  • CS4032 : L’opérateur 'await ne peut être utilisé que dans une méthode asynchrone. Envisagez de marquer cette méthode avec le modificateur « async » et de remplacer son type de retour par «Task<T> ».
  • CS4033 : L’opérateur 'await ne peut être utilisé que dans une méthode asynchrone. Envisagez de marquer cette méthode avec le modificateur «async » et de remplacer son type de retour par «Task ».
  • CS8892 : La méthode n’est pas utilisée comme point d’entrée, car un point d’entrée synchrone a été trouvé.
  • CS9123 : L’opérateur '&' ne doit pas être utilisé sur les paramètres ou les variables locales dans les méthodes asynchrones.
  • CS9330 : 'MethodImplAttribute.Async' ne peut pas être appliqué manuellement aux méthodes. Marquez la méthode « async ».

Conditions requises pour l’expression Await

  • CS1985 : Impossible d'utiliser await dans une instruction catch.
  • CS1986 : 'await' exige que le type ait une méthode 'GetAwaiter' appropriée.
  • CS1992 : L’opérateur 'await' ne peut être utilisé que lorsqu’il est contenu dans une méthode ou une expression lambda marquée avec le modificateur 'async' .
  • CS1995 : L’opérateur 'await' peut uniquement être utilisé dans une expression de requête dans la première expression de collection de la clause 'from' initiale ou dans l’expression de collection d’une clause 'join' .
  • CS1996 : Impossible d’attendre dans le corps d’une instruction de verrouillage.
  • CS4008 : Impossible d’attendre 'void'.
  • CS4032 : L’opérateur 'await ne peut être utilisé que dans une méthode asynchrone. Envisagez de marquer cette méthode avec le modificateur «async » et de remplacer son type de retour par «Task<T> ».
  • CS4033 : L’opérateur 'await ne peut être utilisé que dans une méthode asynchrone. Envisagez de marquer cette méthode avec le modificateur «async » et de remplacer son type de retour par «Task ».

Pour utiliser correctement l’opérateur await , suivez ces règles. Pour plus d’informations, consultez Programmation asynchrone avec async et await.

  • N’utilisez await pas dans les clauses catch (CS1985). Bien que vous puissiez utiliser await dans les blocs try et enfin (en C# 6 et versions ultérieures), les blocs catch présentent des défis spéciaux avec la gestion des exceptions et le flux de contrôle.
  • N’utilisez pas await à l’intérieur des blocs d’instructions lock (CS1996). Le compilateur ne prend pas en charge cela pour éviter d’émettre du code susceptible d’interblocages.
  • Utilisez await uniquement à des emplacements spécifiques dans les expressions de requête (CS1995) : dans la première expression de collection de la clause from initiale, ou dans l’expression de collection d’une clause join.
  • Marquez des méthodes ou des expressions lambda avec le async modificateur avant d’utiliser await (CS1992, CS4032, CS4033).
  • Vérifiez que les types attendus ont une méthode accessible GetAwaiter qui retourne un type awaiter (CS1986).
  • N'appliquez pas await aux expressions de type void (CS4008).
  • Modifiez le type de retour pour Task pour les méthodes qui ne retournent pas de valeur, ou Task<T> pour les méthodes qui retournent une valeur.

Exigences de signature de méthode asynchrone

  • CS1983 : Étant donné qu’il s’agit d’une méthode asynchrone, l’expression de retour doit être de type «Task<T> » plutôt que «T ».
  • CS1994 : Le modificateur 'async' ne peut être utilisé que dans les méthodes qui ont un corps.
  • CS4009 : un point d’entrée vide ou int ne peut pas être asynchrone.
  • CS8892 : La méthode n’est pas utilisée comme point d’entrée, car un point d’entrée synchrone a été trouvé.
  • CS9330 : 'MethodImplAttribute.Async' ne peut pas être appliqué manuellement aux méthodes. Marquez la méthode 'async'.

Pour déclarer correctement les méthodes asynchrones, suivez ces exigences de signature. Pour plus d’informations, consultez les valeurs de retour principales Async.

  • Retourne l’un des types valides : void, Task, Task<T>, un type de type de tâche, IAsyncEnumerable<T>ou IAsyncEnumerator<T> (CS1983).
  • Utilisez le modificateur uniquement sur les async méthodes avec un corps (CS1994). Supprimez le modificateur async sur les méthodes abstraites dans les interfaces ou les classes.
  • Mettez à jour vers C# 7.1 ou une version ultérieure pour utiliser async au point d'entrée Main, ou évitez d'utiliser async comme point d'entrée dans les versions antérieures (CS4009).
  • Supprimez les points d’entrée synchrones si vous avez à la fois des points d’entrée synchronisés et asynchrones (CS8892).
  • Utilisez le async mot clé au lieu d’appliquer MethodImplAttribute.Async manuellement (CS9330).

Pratiques asynchrones

  • CS1989 : Les expressions lambda asynchrones ne peuvent pas être converties en arborescences d’expressions.
  • CS1991 : « Type » ne peut pas implémenter « événement », car il s’agit d’un événement Windows Runtime et « événement » est un événement .NET standard.
  • CS1997 : Étant donné que la fonction est une méthode asynchrone qui retourne une valeur, un mot clé de retour ne doit pas être suivi d’une expression d’objet.
  • CS1998 : cette méthode asynchrone n’a pas d’opérateurs «await » et s’exécute de manière synchrone. Envisagez d’utiliser l’opérateur «await » pour attendre des appels d’API non bloquants, ou «await Task.Run(...) pour effectuer un travail lié au processeur sur un thread d’arrière-plan.
  • CS4014 : Étant donné que cet appel n’est pas attendu, l’exécution de la méthode actuelle se poursuit avant la fin de l’appel. Envisagez d’appliquer l’opérateur await au résultat de l’appel.
  • CS9123 : L’opérateur '&' ne doit pas être utilisé sur les paramètres ou les variables locales dans les méthodes asynchrones.

Pour écrire du code asynchrone correctement et éviter les pièges courants, suivez ces bonnes pratiques. Pour plus d’informations, consultez Programmation asynchrone avec async et await.

  • Attendez toujours les appels aux méthodes asynchrones qui retournent Task ou Task<TResult> (CS4014). Les appels inattendus peuvent entraîner des exceptions perdues et un comportement inattendu.
  • Ne retournez pas de valeur à partir de méthodes asynchrones qui retournent Task (non générique) ; utilisez Task<T> plutôt (CS1997).
  • Incluez au moins un await opérateur dans des méthodes asynchrones ou supprimez le async modificateur (CS1998).
  • Supprimez l’instruction return si la méthode doit retourner Task (CS1997, CS1998).
  • Modifiez le type de retour de la méthode pour Task<T> renvoyer une valeur (CS1997, CS1998).
  • Supprimez le modificateur async et retournez la tâche directement si vous n’avez pas besoin de la machine d'état asynchrone (CS1997, CS1998).
  • N’utilisez pas de méthodes asynchrones dans les arborescences d’expressions (CS1989). Les arborescences d’expressions représentent du code en tant que données et ne prennent pas en charge les transformations complexes d’ordinateurs d’état requises par les méthodes asynchrones.
  • Ne marquez pas les accesseurs d’ajout ou de suppression dans une interface ou un événement WinRT comme asynchrone (CS1991). Il s’agit d’une restriction spécifique à la plateforme pour l’interopérabilité de Windows Runtime.
  • Évitez d’utiliser l’opérateur d’adresse (&) sur les expressions à l’intérieur des méthodes asynchrones (CS9123). La cible peut être déplacée en mémoire pendant la suspension, ce qui rend le pointeur non valide.