Comment faire pour forcer async enfant remplace en C# 5.0
Je suis en train de travailler sur un système dans lequel plusieurs objets sont appelés à mettre en œuvre une fonction particulière par l'intermédiaire d'une interface, et je veux que la fonction à exécuter de manière asynchrone avec les continuations (je m'attends à des implémentations à I/O-lié et vous voulez vous assurer que tous les objets client de remplir cette fonction dès que possible). Je suis l'aide de Visual Studio Async CTP de Rafraîchissement pour le SP1, avec C# "5.0".
Qu'est-ce que la pratique recommandée pour l'application de comportement asynchrone dans les objets enfants de ma classe abstraite (voir ci-dessous)? Je ne peux pas (apparemment), imposer l'utilisation de "asynchrone" méthodes en utilisant la méthode virtuelle approche. Je peux seulement besoin d'une "Tâche" type de retour. Est-ce à dire que je ne devrait pas essayer d'exiger un comportement asynchrone lors de tous les objets enfants? Dans ce cas, si le type de retour d'être simplement "vide"?
L'interface publique est une conséquence malheureuse de la conception du système, pour l'instant, mais c'est une question distincte. Évidemment, je ne pouvais pas contraindre quelqu'un à être asynchrone qui contourne 'BaseFoo' et met en œuvre la "IFoo' interface.
Voici le code:
public interface IFoo
{
void Bar(); //NOTE: Cannot use 'async' on methods without bodies.
}
public abstract class BaseFoo : IFoo
{
public async void Bar()
{
await OnBar(); //QUESTION: What is the right "async delegation" pattern?
}
protected virtual async Task OnBar()
{
await TaskEx.Yield();
}
}
public class RealFoo : BaseFoo //NOTE: May be implemented by 3rd party
{
protected override async Task OnBar()
{
//CLIENT: Do work, potentially awaiting async calls
await TaskEx.Yield(); //SECONDARY QUESTION: Is there a way to avoid this if there are no 'awaits' in the client's work?
}
}
Vous devez vous connecter pour publier un commentaire.
De savoir si une méthode est implémentée à l'aide de
async
/await
ou pas, c'est un mise en œuvre détail. Comment la méthode doit se comporter est un contrat de détails, qui doit être spécifié dans les conditions normales.Notez que si vous faites de la méthode de retour d'un
Task
ou unTask<T>
, il est plus évident que c'est censé être asynchrone, et sera sans doute difficile à mettre en œuvre sans être asynchrone.D'autre part, s'il y a une mise en œuvre (p. ex. à des fins de test) où la
await
expressions jamais être incomplète, pourquoi voulez-vous forcer quelqu'un à écrire une méthode asynchrone sansawait
appels de toute façon? Vous êtes attend implémentations à IO-lié, mais il y aura peut-être des cas particuliers où les implémentations souhaitez utiliser codée en dur de données, etc.Fondamentalement, vous avez à gérer cela dans la documentation de la méthode - si vous ne pouvez pas faire confiance exécutants de lire ça, vous avez pas de chance quand même 🙁
Task
type de retour plutôt que devoid
partout où vous le pouvez -void
est surtout là pour que vous puissiez mettre en œuvre des gestionnaires d'événements avec des méthodes asynchrones. Il est souvent pratique pour être en mesure d'attendre pour une méthode asynchrone à compléter, etc - etTask
simplifie la tâche.En plus Jon réponse, si vous êtes à la suite de la Basée sur les tâches du Modèle Asynchrone ensuite vos noms de méthode doit être suffixé avec
Async
, qui soi-même les documents qu'il est une méthode asynchrone.Si vous êtes à la mise en œuvre d'une interface
il devrait être évident que cela devrait être mis en œuvre avec la
async
mot-clé.