Це ключове слово прибутковості C # в дії - воно не робить нічого особливого з www
об'єктом, скоріше означає щось особливе для методу, який міститься в ньому. Зокрема, це ключове слово можна використовувати лише в методі, який повертає IEnumerable
(або IEnumerator
), і використовується щоб вказати, який об'єкт буде повернутий перелічувачем при виклику MoveNext .
Це працює тому, що компілятор перетворює весь метод в окремий клас, який реалізує IEnumerable
(або IEnumerator
) за допомогою машини машини - чистий результат полягає в тому, що тіло методу не виконується, поки хтось не перерахує через повернене значення. Це буде працювати з будь-яким типом, в цьому немає абсолютно нічого особливого WWW
, скоріше його особливий метод, що містить.
Погляньте на те, що за кадром ключового слова врожаю C #, щоб дізнатися, який код генерує компілятор C #, або просто експериментуйте та огляньте код, використовуючи щось на зразок IL Spy
Оновлення: для уточнення
- Коли Unity викликає підпрограму, яка містить
yield return
оператор, все, що трапляється, - це повернення нумератора - жоден з методів не виконується в цей момент
- Щоб отримати тіло методу для виконання Unity, необхідно зателефонувати
MoveNext
на ітератор, щоб отримати перше значення в послідовності. Це призводить до того, що метод виконує до першого yeild return
оператора, після чого абонент поновлюється (і, мабуть, Unity продовжує виводити решту кадру)
- Як я це розумію, Unity зазвичай продовжує викликати
MoveNext
метод на ітераторі раз у кожному наступному кадрі, змушуючи метод виконувати знову до наступного yield return
оператора, коли кожен кадр, доки не буде досягнуто кінця методу чи yield break
оператора (із зазначенням кінець послідовності)
Єдиний спеціальний біт тут (і в декількох з інших випадків ) є те , що Unity не просувається цю конкретну итератор наступного кадру, замість цього він просуває тільки итератор (що викликав метод для продовження виконання) , коли завантаження завершена. Хоча, здається, існує базовий клас YieldInstruction, який, імовірно, містить загальний механізм передачі сигналу Unity, коли ітератор повинен бути вдосконалений, WWW
клас, схоже, не успадковує цей клас, тому я можу лише припускати, що існує особливий випадок для цього класу в двигуні Unity.
Щоб було зрозуміло - yield
ключове слово не робить нічого особливого для WWW
класу, скоріше, це особлива обробка, яку Unity надає членам повернутого перерахування, що викликає таку поведінку.
Оновіть друге: Що стосується механізму, який WWW
використовує для асинхронного завантаження веб-сторінок, він, ймовірно, використовує або метод HttpWebRequest.BeginGetResponse, який буде внутрішньо використовувати асинхронний IO, або в якості альтернативи, він може використовувати нитки (або створюючи виділений потік, або використовуючи пул потоків).
yield return
для асинхронних операцій - це злом. У "справжній" програмі C # ви використовуєтеTask
для цього. Unity, ймовірно, не використовує їх, оскільки він був створений раніше .Net 4.0, коли вінTask
був представлений.