2010-10-28 15 views
43

Microsoft anunció el Visual Studio Async CTP hoy (28 de octubre de 2010) que introduce las palabras clave async y await en C#/VB para la ejecución asíncrona del método.C# Async - ¿Cómo funciona?

principio pensé que el compilador traduce las palabras clave en la creación de un hilo, pero de acuerdo con el white paper y Anders Hejlsberg de PDC presentation (a 31:00) la operación asincrónica pasa por completo en el hilo principal.

¿Cómo puedo hacer que una operación se ejecute en paralelo en el mismo hilo? ¿Cómo es técnicamente posible y cuál es la característica realmente traducida en IL?

Respuesta

73

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.

6

lo que tengo entendido, lo que los async y await palabras clave que hacen es que cada vez que un método async emplea la palabra clave await, el compilador convertir el resto del método en una continuación que está programado cuando se haya completado la operación asíncrona. Eso permite que los métodos async regresen a la persona que llama de inmediato y reanude el trabajo cuando se realiza la parte asincrónica.

De acuerdo con los documentos disponibles hay muchos detalles, pero a menos que esté equivocado, esa es la esencia de la misma.

Como lo veo, el propósito de los métodos asíncronos no es ejecutar una gran cantidad de código en paralelo, sino cortar los métodos asíncronos en varios trozos pequeños, que pueden llamarse según sea necesario. El punto clave es que el compilador manejará todo el complejo cableado de devoluciones de llamadas mediante tareas/continuaciones. Esto no solo reduce la complejidad, sino que permite que el método asíncrono se escriba más o menos como el código síncrono tradicional.

+2

¿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? –

+0

@ 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. –

43

¿Cómo puedo tener una operación ejecutada en paralelo en el mismo hilo?

No puede. La asincronía no es "paralelismo" o "concurrencia". La asincronía podría implementarse con paralelismo, o podría no serlo. Podría implementarse dividiendo el trabajo en pequeños trozos, poniendo cada porción de trabajo en una cola y luego ejecutando cada porción de trabajo siempre que el hilo no esté haciendo otra cosa.

Tengo toda una serie de artículos en mi blog sobre cómo funciona todo esto; el directamente relacionado con esta pregunta probablemente subirá el jueves de la próxima semana. Ver

http://blogs.msdn.com/b/ericlippert/archive/tags/async/

para más detalles.