2016-11-14 1 views
1

Je travaille avec une DLL tierce qui expose des méthodes qui renvoient Task et Task<T>. Je n'ai aucun contrôle sur cet assemblage ou l'interface, et je suppose que l'auteur a supposé que tout devrait être asynchrone car les noms des méthodes sont * Async() comme indiqué ci-dessous. Par conséquent, comment implémenter correctement l'interface si je n'ai aucun code asynchrone en cours d'exécution?Comment gérez-vous une interface tierce qui renvoie la tâche si vous n'avez pas de code asynchrone?

public interface IFoo 
{ 
    Task DoWorkAsync(); 

    Task<int> GetValueAsync(); 
} 

Ma tentative a été la suivante:

public class FooBar : IFoo 
{ 
    public async Task DoWorkAsync() 
    { 
     // Do Some Work 

     await Task.Yield(); 
    } 

    public async Task<int> GetValueAsync() 
    { 
     // Do Some Work 
     var result = ...; 

     return Task.FromResult(result); 
    } 
} 

De plus:

  • L'auteur était correct à exposer seulement des méthodes qui sont retournés Task/Task<T>?
  • L'auteur a-t-il corrigé les noms de méthode de suffixation avec * Async()? L'analyse de code ne se plaint pas si j'écris une méthode asynchrone sans ajouter Async au nom.
+2

Je dirais oui sur les méthodes d'appel 'Async'. Rend clair et simple, esp. lorsque vous mettez à niveau et essayez de rendre les choses rétrocompatibles avec les méthodes 'GetSomething' et' GetSomethingAsync'. – rbm

+0

Je fais généralement la première de vos deux approches. S'il n'y a rien à attendre, il n'y a rien à attendre. Cela semble inutile, mais les bibliothèques tierces sont ce qu'elles sont. – David

+0

@David: Il n'y a pas deux approches montrées, ce sont deux méthodes différentes, dont l'une techniquement n'a pas de retour, c'est pourquoi c'est juste 'Task' au lieu de' Task '. – michael

Répondre

3

Si vous n'avez pas de travail asynchrone à faire, n'incluez pas le mot-clé async. Votre fonction GetValueAsnyc était presque correcte, vous avez juste besoin de laisser tomber le async. Pour votre DoWorkAsync vous ne devriez pas marquer la méthode async et retourner une tâche terminée.

public class FooBar : IFoo 
{ 
    public Task DoWorkAsync() 
    { 
     // Do Some Work 

     //If you can use .NET 4.6 
     return Task.CompletedTask; 

     //For older versions, the thing you pass in does not matter, I like to use bool. 
     return Task.FromResult(false); 
    } 

    public Task<int> GetValueAsync() 
    { 
     // Do Some Work 
     var result = ...; 

     return Task.FromResult(result); 
    } 
} 

Cependant, si votre code est lent et vous finissez par bloquer l'interface utilisateur pendant une longue période de temps, je considérerais la recherche pour si vous pouvez ré-écrire votre code comme en fait être async ou peut-être envelopper le code dans un fil de fond, mais je ne ferais un fil de fond que si c'était un dernier recours.