Ответ 1
Он работает аналогично ключевому слову yield return
в С# 2.0.
Асинхронный метод на самом деле не является обычным последовательным методом. Он скомпилирован в конечный автомат (объект) с некоторым состоянием (локальные переменные превращаются в поля объекта). Каждый блок кода между двумя применениями await
является одним "шагом" конечного автомата.
Это означает, что когда метод запускается, он просто запускает первый шаг, а затем конечный автомат возвращает и планирует выполнение некоторых работ. Когда работа будет выполнена, он выполнит следующий этап конечного автомата. Например, этот код:
async Task Demo() {
var v1 = foo();
var v2 = await bar();
more(v1, v2);
}
Будет переведено на что-то вроде:
class _Demo {
int _v1, _v2;
int _state = 0;
Task<int> _await1;
public void Step() {
switch(this._state) {
case 0:
this._v1 = foo();
this._await1 = bar();
// When the async operation completes, it will call this method
this._state = 1;
op.SetContinuation(Step);
case 1:
this._v2 = this._await1.Result; // Get the result of the operation
more(this._v1, this._v2);
}
}
Важная часть состоит в том, что он просто использует метод SetContinuation
, чтобы указать, что, когда операция завершается, он должен снова вызвать метод Step
(и метод знает, что он должен запустить второй бит исходного кода, используя поле _state
). Вы легко можете себе представить, что SetContinuation
будет чем-то вроде btn.Click += Step
, который будет работать полностью на одном потоке.
Модель асинхронного программирования в С# очень близка к асинхронным рабочим процессам F # (на самом деле это, по сути, одно и то же, кроме некоторых технических деталей), и писать реактивные однопоточные графические приложения с использованием async
довольно интересно область - по крайней мере, я так думаю - см., например, в этой статье (возможно, мне стоит написать версию С#: -)).
Перевод похож на итераторы (и yield return
), и на самом деле было возможно использовать итераторы для реализации асинхронного программирования на С# раньше. Я написал статью об этом некоторое время назад - и я думаю, что он все равно может дать вам некоторое представление о том, как работает перевод.