Funciona de manera similar a la palabra clave yield return
en C# 2.0.
Un método asincrónico no es en realidad un método secuencial ordinario. Se compila en una máquina de estado (un objeto) con algún estado (las variables locales se convierten en campos del objeto). Cada bloque de código entre dos usos de await
es un "paso" de la máquina de estado.
Esto significa que cuando se inicia el método, solo ejecuta el primer paso y luego la máquina de estados regresa y programa el trabajo por realizar: cuando el trabajo finalice, se ejecutará el siguiente paso de la máquina de estados. Por ejemplo, este código:
async Task Demo() {
var v1 = foo();
var v2 = await bar();
more(v1, v2);
}
se traduciría a algo como:
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);
}
}
La parte importante es que sólo utiliza el método SetContinuation
para especificar que al finalizar la operación, se debe llamar a la Step
método de nuevo (y el método sabe que debe ejecutar el segundo bit del código original utilizando el campo _state
). Puede imaginarse fácilmente que el SetContinuation
sería algo así como btn.Click += Step
, que se ejecutaría completamente en un único hilo. El modelo de programación asíncrono en C# está muy cerca de los flujos de trabajo asíncronos F # (de hecho, es esencialmente lo mismo, aparte de algunos detalles técnicos), y la escritura de aplicaciones GUI de un solo hilo reactivo usando async
es un área bastante interesante - al menos eso creo - ver por ejemplo this article (tal vez debería escribir una versión C# ahora :-)).
La traducción es similar a los iteradores (y yield return
) y, de hecho, fue posible utilizar iteradores para implementar la programación asincrónica en C# antes. Escribí an article about that hace un tiempo, y creo que todavía puede darle una idea de cómo funciona la traducción.
¿Cómo está programado sin un hilo separado? ¿Es una continuación un concepto específico en el CLR que permite una programación ligera? –
@ 0xA3: Creo que el documento dice que el método asíncrono no se ejecuta en su propio hilo. Es decir. al igual que TPL, será una mezcla del hilo actual y los hilos del grupo de subprocesos dependiendo de la situación. –