Il s'agit du mot-clé C # yield en action - il ne fait rien de spécial avec l' wwwobjet, il signifie plutôt quelque chose de spécial pour la méthode dans laquelle il est contenu. Plus précisément, ce mot-clé ne peut être utilisé que dans une méthode qui renvoie un IEnumerable(ou IEnumerator), et est utilisé pour indiquer quel objet sera "renvoyé" par l'énumérateur lorsque MoveNext est appelé.
Cela fonctionne parce que le compilateur convertit la méthode entière en une classe distincte qui implémente IEnumerable(ou IEnumerator) à l'aide d'une machine d'état - le résultat net est que le corps de la méthode elle-même n'est pas exécuté jusqu'à ce que quelqu'un énumère via la valeur de retour. Cela fonctionnera avec n'importe quel type, il n'y a absolument rien de spécial WWW, c'est plutôt la méthode conteneur qui est spéciale.
Jetez un œil aux coulisses du mot-clé de rendement C # pour en savoir plus sur le type de code généré par le compilateur C #, ou expérimentez et inspectez le code vous-même en utilisant quelque chose comme IL Spy
Mise à jour: pour clarifier
- Lorsque Unity appelle une coroutine contenant une
yield returninstruction, tout ce qui se passe est qu'un énumérateur est renvoyé - aucun des corps de méthode n'est exécuté à ce stade
- Pour que le corps de la méthode s'exécute, Unity doit appeler
MoveNextl'itérateur afin d'obtenir la première valeur de la séquence. Cela provoque l'exécution de la méthode jusqu'à la première yeild returninstruction, moment auquel l'appelant reprend (et vraisemblablement Unity continue de rendre le reste de la trame)
- Si je comprends bien, Unity continue ensuite d'appeler la
MoveNextméthode sur l'itérateur une fois par trame suivante, ce qui fait que la méthode s'exécute à nouveau jusqu'à l' yield returninstruction suivante une fois par trame, jusqu'à ce que la fin de la méthode ou une yield breakinstruction soit atteinte (indiquant la fin de la séquence)
Le bit spécial seulement ici (et dans deux ou trois d' autres cas ) est que l' unité ne fait pas avancer ce iterator particulier la trame suivante, au lieu , il avance que la iterator ( ce qui provoque la méthode pour poursuivre l' exécution) lorsque le téléchargement est terminé. Bien qu'il semble y avoir une classe YieldInstruction de base qui contient vraisemblablement un mécanisme générique pour signaler à Unity quand un itérateur doit être avancé, la WWWclasse ne semble pas hériter de cette classe, donc je ne peux que supposer qu'il existe un cas spécial pour cette classe dans le moteur Unity.
Juste pour être clair - le yieldmot-clé ne fait rien de spécial pour la WWWclasse, c'est plutôt le traitement spécial que Unity donne aux membres de l'énumération retournée qui provoque ce comportement.
Mettez à jour la seconde: en ce qui concerne le mécanisme qui WWWutilise pour télécharger les pages Web de manière asynchrone, il utilise probablement la méthode HttpWebRequest.BeginGetResponse qui utilisera en interne des E / S asynchrones ou bien il pourrait utiliser des threads (soit en créant un thread dédié, soit en utilisant un pool de threads).
yield returnpour les opérations asynchrones est un hack. Dans un "vrai" programme C #, vous utiliseriez unTaskpour cela. Unity ne les utilise probablement pas car il a été créé avant .Net 4.0, lors deTaskson introduction.