Interfaces et méthodes asynchrones

J’ai une application Cette application utilise une interface pour accéder à la firebase database. Cette interface peut être implémentée par de nombreuses classes. Par exemple, on utilise EF 4.4, mais d’autres classes peuvent utiliser EF5 qui est plus efficace. À l’avenir, j’utiliserai peut-être EF6 car il utilise des méthodes asynchrones. Dans cet exemple, toutes les méthodes utilisent EF, mais d’autres options peuvent être utilisées.

L’application est codée une fois, en utilisant l’interface, et selon le fichier de configuration, utilisez une implémentation ou l’autre, il suffit donc de modifier le code dans un seul endroit, le constructeur, pour append la nouvelle option dans l’instanciation de la classe qui est affecté à l’interface.

Pour le moment, toutes les méthodes des classes ne sont pas async , mais si j’utilise EF6, je souhaiterais utiliser les méthodes asynchrones, donc je ne sais pas s’il est possible que la classe qui utilise EF6 et implémente l’interface peut utiliser les méthodes async .

Pour les méthodes asynchrones de EF6, j’utiliserais le modèle async / awiat, donc dans la méthode de ma classe, je dois utiliser l’atsortingbut async. Cela me permet d’utiliser le mot-clé wait lorsque j’appelle à la méthode asynchrone de EF6.

Mais cette classe peut implémenter l’interface qui est dans un premier temps pour les méthodes synchrones?

Existe-t-il un moyen dans l’application principale d’utiliser de nombreuses implémentations sans avoir à modifier le code? Certaines implémentations utiliseront des méthodes asynchrones tandis que d’autres seront synchrones.

async ne fait pas partie de la signature, vous n’avez donc pas besoin de vous soucier de savoir si la méthode implémentant l’interface est async ou non, il vous suffit de vous préoccuper des types de propriétés, du type de retour, du nom de la méthode et accessibilité.

La vraie différence est que vos méthodes async devront renvoyer une Task ou une Task , alors que les méthodes non asynchrones renvoient le plus souvent de type void ou de type T directement.

Si vous voulez “tester l’avenir”, une option consiste à vérifier que toutes vos interfaces renvoient la Task ou la Task et que, pour vos implémentations EF4 / EF5, vous encapsulez vos résultats même si elles sont exécutées de manière synchrone. .

Task.FromResult été ajouté à .NET 4.5, mais si vous ne l’avez pas, vous pouvez écrire votre propre assez facilement:

 public static Task FromResult(T result) { var tcs = new TaskCompletionSource(); tcs.SetResult(result); return tcs.Task; } 

Vous pouvez également écrire une méthode CompletedTask qui renvoie simplement une tâche déjà terminée: (elle met en cache une seule tâche pour des raisons d’efficacité).

 private static Task _completedTask; public static Task CompletedTask() { return _completedTask ?? initCompletedTask(); } private static Task initCompletedTask() { var tcs = new TaskCompletionSource(); tcs.SetResult(null); _completedTask = tcs.Task; return _completedTask; } 

Ces deux méthodes simplifieront le processus consistant à faire en sorte que toutes vos méthodes renvoient un certain type de Task , bien que cela rende votre code un peu plus compliqué jusqu’à ce que vous puissiez utiliser C # 5.0 pour pouvoir await le résultat.