Все демонстрации

Как async/await разворачивается в state machine

Проследите, как компилятор преобразует async-метод: вызовы MoveNext, остановка на await, планирование continuation и завершение Task.

Текущий этап Готово
Шаг0 / 7
State
Возвращённый Taskне создан
Исполняющий потокпоток вызывающего кода
Сохранённый awaiterнет

Исходный async-метод

Код, который пишет разработчик.

async Task<string> LoadProfileAsync()
{
    Log("start");
    var user = await GetUserAsync();
    var score = await GetScoreAsync(user);
    return $"{user}: {score}";
}

State machine от компилятора

Структура переживает остановки и хранит локальные переменные в полях.

var machine = new <LoadProfileAsync>d__0();
machine.MoveNext();
state = 0; builder.AwaitUnsafeOnCompleted(...);
awaiter.GetResult(); state = -1;
state = 1; builder.AwaitUnsafeOnCompleted(...);
state = -2; builder.SetResult(result);

Выполнение в Runtime

Пока идёт I/O, поток освобождён — прогресс хранит state machine.

1Вызывающий код
2MoveNext()
3I/O пользователя
4Очередь continuation
5I/O рейтинга
6SetResult()

Метод ещё не вызван: state machine и Task пока не существуют.