Question

En python le mot-clé de rendement peut être utilisé à la fois pousser et tirer des contextes, je sais comment faire le contexte de traction en c #, mais comment pourrais-je obtenir la poussée. Je posterai le code que je suis en train de répliquer en c # de python:

def coroutine(func):
  def start(*args,**kwargs):
    cr = func(*args,**kwargs)
    cr.next()
    return cr
  return start

@coroutine
def grep(pattern):
  print "Looking for %s" % pattern
  try:
    while True:
      line = (yield)
      if pattern in line:
        print line,
  except GeneratorExit:
    print "Going away. Goodbye"
Était-ce utile?

La solution

Si ce que vous voulez est une « collection observable » - qui est, une collection qui pousse des résultats à vous plutôt que de laisser le consommateur les tirer - alors vous voudrez probablement regarder dans les extensions de cadre réactif. Voici un article sur elle:

http://www.infoq.com/news/ 2009/07 / réactifs-cadre-LINQ-Events

Maintenant, comme vous le constatez, vous pouvez construire à la fois « push » et « pull » de style itérateurs facilement si vous avez coroutines disponibles. (Ou, comme Thomas souligne, vous pouvez les construire avec continuations aussi bien.) Dans la version actuelle de C # nous n'avons pas vrai coroutines (ou continuations). Cependant, nous sommes très préoccupés par les utilisateurs de la douleur se sentent autour programmation asynchrone .

La mise en œuvre coroutines à base de fibres comme une caractéristique de la langue de première classe est une technique qui pourrait éventuellement être utilisée pour rendre la programmation asynchrone plus facile, mais qui est juste une idée possible de beaucoup que nous sommes à l'heure actuelle des recherches. Si vous avez un scénario génial vraiment solide où coroutines faire un meilleur travail que toute autre chose - y compris le cadre réactif - j'aimerais en savoir plus à ce sujet. Les données plus réalistes que nous avons sur ce réels problèmes que les gens sont confrontés à la programmation asynchrone, plus il est probable que nous sommes de trouver une bonne solution. Merci!

Mise à jour: Nous avons récemment annoncé que nous ajoutons des flux de contrôle asynchrone comme coroutine à la prochaine version de C # et VB. Vous pouvez essayer vous-même avec notre édition Community Technology Preview, que vous pouvez télécharger ici .

Autres conseils

C # ne pas général co-routines. Un co-routine générale est où la co-routine a sa propre pile, à savoir elle peut appeler d'autres méthodes et ces procédés peuvent valeurs « rendement ». La mise en œuvre de co-routines générales nécessite de faire des choses intelligentes avec des piles, peut-être jusqu'à et y compris l'allocation des cadres de pile (les structures cachées qui contiennent des variables locales) sur le tas. Cela peut être fait, certaines langues font que (par exemple le schéma), mais il est un peu difficile de le faire correctement. En outre, la plupart des programmeurs la fonction difficile à comprendre.

co-routines générales peuvent être émulés avec des fils. Chaque thread a sa propre pile. Dans une configuration co-routine, les deux fils (l'appelant initial, et le fil pour la co-routine) alterneront contrôle, ils ne courent pas en même temps. Le mécanisme de « rendement » est alors un échange entre les deux fils, et en tant que telle, elle est chère (synchronisation, un aller-retour à travers le noyau du système d'exploitation et un planificateur, ...). De plus, il y a beaucoup de place pour les fuites de mémoire (la co-routine doit être explicitement « arrêté », sinon le fil d'attente collera pour toujours). Ainsi, cela se fait rarement.

C # fournit une fonction de co-routine bâtarde-down appelé itérateurs . Le compilateur C # convertit automatiquement le code iterator dans une classe d'état spécifique, avec des variables locales deviennent des champs de classe. Cédant est alors, au niveau VM, une return plaine. Une telle chose est faisable aussi longtemps que le « rendement » est réalisé à partir du code iterator lui-même, et non à partir d'une méthode que le code iterator invoque. C # itérateurs couvrent déjà de nombreux cas d'utilisation et les C # concepteurs ne voulaient pas aller plus loin sur la route . Certaines personnes sarcastiques sont prêts à affirmer que la mise en œuvre des continuations fonctionnalités complètes aurait empêché C # d'être aussi efficace que son arc ennemi Java (continuations efficaces sont réalisables, mais cela nécessite un certain travail avec le GC et le compilateur JIT).

Merci @NickLarsen, vous m'a aidé à me souviens les nouveautés qui ont introduit MS, l'interface IObservable.

lien

http://msdn.microsoft.com /en-us/library/dd783449(VS.100).aspx

En fait, .NET ne fait pas « hypothèses erronées » sur l'affinité du fil, en fait, il découple totalement la notion d'un fil de niveau .NET à partir du fil de niveau OS.

Qu'est-ce que vous avez à faire est d'associer un état logique de fil .NET avec votre fibre (pour que vous avez besoin de l'API d'hébergement CLR de mais vous n'avez pas besoin d'écrire vous-même hôte que vous pouvez utiliser celles qui sont nécessaires à partir de votre propre application directement) et tout, suivi de verrouillage, la gestion des exceptions fonctionne à nouveau normalement.

Un exemple peut être trouvé ici: http://msdn.microsoft. com / fr-fr / magazine / cc164086.aspx

BTW Mono 2.6 contient un faible niveau de soutien Coroutine et peut être utilisé pour mettre en œuvre facilement toutes les primitives de niveau supérieur.

J'aimerais voir une API à base de fibres pour .Net.

J'ai essayé d'utiliser l'API de fibre native en C # par p / invoquer un certain temps, mais parce que la manipulation de l'exception de l'exécution (à tort) fait des hypothèses sur la base fil, les choses ont éclaté (mal) lorsque des exceptions se sont passées.

One "killer app" pour une API coroutine à base de fibres est la programmation de jeux; certains types d'IA ont besoin d'un fil « léger » que vous pouvez tranche de temps à volonté. Par exemple, les arbres de comportement de jeu nécessitent la capacité de « impulsion » le code de décision chaque image, ce qui permet le code AI pour revenir en coopération à l'céder appelant lorsque la tranche de décision appartient. Ceci est possible de mettre en œuvre avec des fils durs, mais beaucoup, beaucoup plus compliqué.

Ainsi, alors que la fibre vrai cas d'utilisation ne sont pas mainstream, ils existent certainement, et une petite niche de nous .Net applaudiraient codeurs si les bogues avec force existants dans le sous-système de fibres ont été élaborés.

Eh bien, j'ai donné un essai le développement d'une bibliothèque complète pour gérer coroutines avec un seul fil. La partie la plus difficile était d'appeler à l'intérieur coroutines coroutines ... et de retourner les paramètres, mais finalement je suis arrivé à un très bon résultat ici . Le seul avertissement est que le blocage des opérations d'E / S doit être fait par des tâches et alll « retour » doit être remplacé par « retour de rendement ». Avec le serveur d'application basé sur cette bibliothèque, j'ai pu presque doubler les demandes avec une norme async / vous attendent basé sur IIS. (Seek pour Node.Cs et Node.Cs.Musicstore sur GitHub pour essayer à la maison)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top