Работает аналогично ключевому слову yield return
в C # 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
, который будет работать полностью в одном потоке.
Модель асинхронного программирования в C # очень близка к асинхронным рабочим процессам F # (фактически, это, по сути, одно и то же, за исключением некоторых технических деталей), и написание реактивных однопоточных приложений с графическим интерфейсом с использованием async
довольно интересно область - по крайней мере, я так думаю - см., например, эту статью (возможно, мне следует написать версию C # сейчас: -)).
Перевод аналогичен итераторам (и yield return
), и фактически было возможно использовать итераторы для реализации асинхронного программирования на C # ранее. Я написал статью об этом некоторое время назад - и я думаю, что она все еще может дать вам некоторое представление о том, как работает перевод.