Мое понимание: GetAPIToken
вызывается, и текущий метод (GetUser
) возвращает объект Task<User>
(который предоставит объект User позже).Выполнение текущего метода продолжается только после возврата метода GetAPIToken
.
Это очень близко.Давайте разберемся с этим двумя способами.
Во-первых, давайте проведем различие между return - что означает, возвращает управление вызывающей стороне - и завершает , что означает, что задача, представленная методом,завершения и либо у нас есть его значение, либо, в случае ненормального завершения, исключение.
В неасинхронных методах нам не нужно проводить различие, потому что возврат управления вызывающей стороне происходит только после завершения.В асинхронных методах мы можем вернуться к вызывающей стороне как приостановка (из-за ожидания незавершенной задачи) или вернуть как завершение (когда представленная задача сигнализируется как завершенная).
Второйполезно выразить рабочий процесс в терминах того, что происходит, если задача завершается при ее создании;скажем, это может произойти в случае кеширования.
Итак, давайте теперь переформулируем ваше понимание с учетом этого:
GetAPIToken
вызывается и возвращает задачу втекущий пользователь. - Если задача завершена, то GetApiToken вернется после завершения всей своей работы.GetUser извлекает токен из выполненной задачи и продолжает работу без приостановки.
- Если задача не выполнена, и это первое ожидание в GetUser, то GetUser создает
Task<User>
GetUser
присваивает остаток от GetUser
как продолжение Task<Token>
и приостанавливает, возвращая Task<User>
- Когда
Task<Token>
завершается, он запускает свое продолжение, которое возобновляет GetUser
, где он оставилoff.
Каков тип / значение токена, пока код ожидает возврата метода GetAPIToken ()?
Хорошо, каково значениеtoken
в эквивалентном не асинхронном случае?Подумайте:
Token x = Foo();
Какое значение x, пока мы ждем завершения Foo?Создание асинхронного Foo не имеет значения;локальному не присваивается значение до тех пор, пока вызов обычно не завершится .Если Foo входит в бесконечный цикл, или если Foo бросает, то x
никогда не назначается.
На практике, конечно, C # назначает всем локальным пользователям их значение по умолчанию, когда они создаются, так что это значение, которое будетбыть в переменной.