Il s'agit du mot-clé C # yield en action - il ne fait rien de spécial avec l' www
objet, 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 return
instruction, 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
MoveNext
l'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 return
instruction, 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
MoveNext
méthode sur l'itérateur une fois par trame suivante, ce qui fait que la méthode s'exécute à nouveau jusqu'à l' yield return
instruction suivante une fois par trame, jusqu'à ce que la fin de la méthode ou une yield break
instruction 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 WWW
classe 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 yield
mot-clé ne fait rien de spécial pour la WWW
classe, 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 WWW
utilise 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 return
pour les opérations asynchrones est un hack. Dans un "vrai" programme C #, vous utiliseriez unTask
pour cela. Unity ne les utilise probablement pas car il a été créé avant .Net 4.0, lors deTask
son introduction.