web-dev-qa-db-fra.com

Création d'une méthode asynchrone dans .NET 4.0 qui peut être utilisée avec "attendent" dans .NET 4.5

J'ai un projet .NET qui utilise C # dans .NET 4.0 et VS2010.

Ce que je voudrais faire, c'est ajouter des surcharges asynchrones à ma bibliothèque pour rendre la programmation asynchrone plus facile pour les utilisateurs de .NET 4.5 avec le mot-clé wait. À l'heure actuelle, les méthodes qui sont surchargées ne sont pas asynchrones. De plus, je ne veux pas utiliser de méthodes asynchrones moi-même, il suffit d'en créer de nouvelles et de les rendre disponibles.

La création de méthodes asynchrones dans .NET 4.0 et VS2010 est-elle possible et si oui, à quoi devrait ressembler la méthode async .NET 4.0?

Parce que j'utilise VS2010, je n'ai pas accès au mot clé "async", alors que doit-il se passer pour émuler ce comportement dans .NET 4.0? Par exemple, doit-il renvoyer un type particulier et un code doit-il se produire à l'intérieur de la méthode pour que le code actuellement non asynchrone qu'il appelle se produise de manière asynchrone?

41

Comme d'autres l'ont dit, vous commencez par avoir une méthode return Task ou Task<TResult>. C'est suffisant pour await son résultat dans .NET 4.5.

Pour que votre méthode s'intègre le mieux possible avec le futur code asynchrone, suivez les instructions du document de modèle asynchrone basé sur les tâches (également disponible sur MSDN ). Il fournit des conventions de dénomination et des recommandations de paramètres, par exemple, pour prendre en charge l'annulation.

Pour l'implémentation de votre méthode, vous avez quelques choix:

32
Stephen Cleary

La façon la plus simple de le faire est de renvoyer un Task ou un Task<T>. Ce sera suffisant.

Cependant, cela n'a de sens que si votre méthode s'exécute réellement de manière asynchrone.

Je vous recommande également de suivre le modèle habituel de les nommer comme AbcAsync (suffixe "Async"). Vos appelants ne remarqueront aucune différence par rapport à une méthode asynchrone créée avec C # 5 (car il n'y en a pas).

Astuce: ajouter simplement async à la méthode ne fait rien. Votre méthode s'exécutera séquentiellement et renverra une tâche terminée. Faire en sorte que la méthode renvoie une tâche doit remplir un certain objectif - généralement, cela est dû au fait que la méthode s'exécute de manière asynchrone (comme un appel de service Web ou un fichier IO).

Si votre méthode ne contient que du calcul mais pas IO (ou seulement bloque les IO), il est généralement préférable de ne pas le rendre asynchrone car vous n'y gagnez rien. Les méthodes asynchrones ne s'exécutent pas toujours sur un thread séparé Si cette dernière phrase vous a surpris, vous voudrez peut-être creuser un peu dans ce sujet.

9
usr

Tant que vous renvoyez une tâche qui se termine d'une manière ou d'une autre (que ce soit dans un thread ou de manière asynchrone), vous prendriez en charge le modèle asynchrone.

Faire exécuter une tâche de manière asynchrone est une autre histoire. Si vous aviez accès au mot clé async et à l'API, vous pourriez simplement baser votre méthode sur des appels asynchrones vers d'autres méthodes asynchrones déjà fournies. Mais dans ce cas, vous devez concevoir à la main vos tâches asynchrones.

Il pourrait y avoir de meilleures façons de le faire, mais la façon la plus élégante que je peux voir (et que j'ai utilisée) est d'utiliser System.Threading.Tasks.TaskCompletionSource pour construire une tâche, utilisez Begin/End modèle de méthodes asynchrones pour exécuter tout ce dont vous avez besoin. Ensuite, lorsque vous avez le résultat en main, postez-le dans l'instance Task précédemment construite à l'aide de votre source d'achèvement.

Ce sera certainement asynchrone, mais pas aussi sophistiqué que ceux de la prochaine version.

Disclaimer: Je ne suis pas du tout près d'un expert en la matière. Je viens de faire quelques expériences.

3
Ekin Koc