Pregunta

Visual Studio Async CTP hoy (28 de octubre de 2010) que introduce el async y await palabras clave en C # / VB para la ejecución del método asíncrono.

En primer lugar pensé que el compilador traduce las palabras clave en la creación de un hilo, pero de acuerdo a la papel blanco y Anders Hejlsberg PDC presentación (al 31:00) la operación asincrónica pasa por completo en el hilo principal.

¿Cómo puedo tener una operación ejecutada en paralelo en el mismo hilo? ¿Cómo es técnicamente posible y lo que es en realidad la función traducida en IL?

¿Fue útil?

Solución

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 ordinaria. Se compila en una máquina de estado (un objeto) con un estado (variables locales se convierten en campos del objeto). Cada bloque de código entre dos usos de await es una "etapa" de la máquina de estado.

Esto significa que cuando el método se inicia, sólo se ejecuta el primer paso y luego los rendimientos de máquina de estados y horarios algún trabajo por hacer - cuando el trabajo está hecho, 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);
}

sería traducido 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 cuando se complete la operación, se debe llamar al método Step de nuevo (y el método sabe que debe ejecutar el segundo bit del código original utilizando el campo _state) . Se puede imaginar fácilmente que el SetContinuation sería algo así como btn.Click += Step, lo que iría por completo en un solo hilo.

El modelo de programación asíncrona en C # es muy cercano a F # flujos de trabajo asíncrono (de hecho, es esencialmente la misma cosa, aparte de algunos detalles técnicos), y escribir las aplicaciones GUI un único subproceso reactivos usando async es una zona bastante interesante - al menos eso creo - Véase, por ejemplo este artículo (tal vez debería escribir una versión de C # ahora: -))

.

La traducción es similar a los iteradores (y yield return) y, de hecho, era posible usar iteradores para implementar la programación asincrónica en C # anterior. Escribí un artículo sobre eso hace un tiempo - y creo que todavía le puede dar un poco conocimiento sobre cómo funciona la traducción.

Otros consejos

  

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

No se puede. La asincronía no es "paralelismo" o "concurrencia" . Asincronía puede ser implementado con el paralelismo, o puede que no sea. Podría ser implementada mediante la ruptura de los trabajos en pequeños trozos, poner cada trozo de trabajo en una cola, y luego ejecutar cada trozo de trabajo cada vez que el hilo pasa a ser no hacer nada más.

Tengo toda una serie de artículos en mi blog acerca de cómo funciona todo esto; la que está directamente relacionado a esta pregunta probablemente va a subir jueves de la próxima semana. Reloj

http://blogs.msdn.com/b/ericlippert/archive / tags / asíncrono /

para más detalles.

A mi entender, lo que la async y palabras clave await 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 para volver a la persona que llama de inmediato y el trabajo hoja de vida cuando la parte asíncrona se realiza.

De acuerdo con los documentos disponibles que hay un montón detalles a la misma, pero si no me engaño, que es la esencia de la misma.

A mi entender el propósito de los métodos asincrónicos no es para ejecutar una gran cantidad de código en paralelo, sino para picar asíncrono métodos en una serie de pequeños trozos, que puede ser llamado como sea necesario. El punto clave es que el compilador se encargará de todo el complejo cableado de devoluciones de llamada utilizando tareas / continuaciones. Esto no sólo reduce la complejidad, pero permite que el método asíncrono a ser escrito más o menos como código síncrono tradicional.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top