Dies ist das C # yield-Schlüsselwort in Aktion - es führt keine besonderen Aktionen mit dem www
Objekt aus, sondern bedeutet etwas Besonderes für die Methode, in der es enthalten ist. Insbesondere kann dieses Schlüsselwort nur in einer Methode verwendet werden, die ein IEnumerable
(oder IEnumerator
) zurückgibt und verwendet wird um anzugeben, welches Objekt vom Enumerator "zurückgegeben" wird, wenn MoveNext aufgerufen wird.
Dies funktioniert, weil der Compiler die gesamte Methode in eine separate Klasse konvertiert, die mithilfe einer Zustandsmaschine implementiert IEnumerable
(oder IEnumerator
). Das Nettoergebnis ist, dass der Hauptteil der Methode selbst erst ausgeführt wird, wenn jemand den Rückgabewert durchführt. Dies funktioniert mit jedem Typ, es ist absolut nichts Besonderes WWW
, sondern die Containing-Methode, die speziell ist.
Werfen Sie einen Blick hinter die Kulissen des Schlüsselworts C # yield, um mehr darüber zu erfahren, welche Art von Code der C # -Compiler generiert, oder testen Sie den Code einfach selbst mit etwas wie IL Spy
Update: Zur Verdeutlichung
- Wenn Unity eine Coroutine aufruft, die eine
yield return
Anweisung enthält , wird lediglich ein Enumerator zurückgegeben. Zu diesem Zeitpunkt wird kein Methodentext ausgeführt
- Damit der Methodentext ausgeführt werden kann, muss Unity
MoveNext
den Iterator aufrufen , um den ersten Wert in der Sequenz abzurufen. Dies führt dazu, dass die Methode bis zur ersten yeild return
Anweisung ausgeführt wird. An diesem Punkt setzt der Aufrufer die Ausführung fort (und vermutlich wird der Rest des Frames von Unity wiedergegeben).
- So wie ich es verstehe, ruft Unity normalerweise die
MoveNext
Methode für den Iterator bei jedem folgenden Frame erneut auf, wodurch die Methode bis zur nächsten yield return
Anweisung bei jedem Frame erneut ausgeführt wird, bis entweder das Ende der Methode oder eine yield break
Anweisung erreicht ist (was anzeigt) das Ende der Sequenz)
Die einzige spezielle Bit hier (und in einem Paar von anderen Fällen ) ist , dass die Einheit nicht diese besondere Iterator es nur den nächsten Frame, stattdessen geht nicht voran den Iterator (die Methode verursacht weiterhin ausgeführt wird ) , wenn der Download abgeschlossen ist. Obwohl es anscheinend eine Basis- YieldInstruction- Klasse gibt, die vermutlich einen generischen Mechanismus für die Signalisierung an Unity enthält, wenn ein Iterator weiterentwickelt werden soll, WWW
scheint die Klasse nicht von dieser Klasse zu erben, sodass ich nur davon ausgehen kann, dass es einen Sonderfall für gibt diese Klasse in der Unity-Engine.
Nur um klar zu sein: Das yield
Schlüsselwort hat keine besonderen Auswirkungen auf die WWW
Klasse, sondern auf die spezielle Behandlung, die Unity den Mitgliedern der zurückgegebenen Aufzählung gibt, die dieses Verhalten verursacht.
Aktualisieren Sie die zweite: Für den Mechanismus, WWW
mit dem Webseiten asynchron heruntergeladen werden, wird wahrscheinlich entweder die HttpWebRequest.BeginGetResponse-Methode verwendet, die intern asynchrone E / A verwendet, oder es können Threads verwendet werden (entweder ein dedizierter Thread erstellt oder ein Threadpool verwendet werden).
yield return
für asynchrone Vorgänge ein Hack ist. In einem "echten" C # -Programm würden SieTask
hierfür a verwenden. Unity verwendet sie wahrscheinlich nicht, da sie vor derTask
Einführung von .Net 4.0 erstellt wurden .