Це ключове слово прибутковості 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був представлений.