Domanda

Visual Studio Async CTP (28 ottobre, 2010) che introduce il async e await parole chiave in C # / VB per l'esecuzione metodo asincrono.

Per prima cosa ho pensato che il compilatore traduce le parole chiave nella creazione di un filo, ma secondo il white paper e di Anders Hejlsberg PDC presentazione (a 31:00) l'operazione asincrona avviene completamente sul filo principale.

Come posso avere un intervento eseguito in parallelo sullo stesso thread? Come è tecnicamente possibile e fino a che è la caratteristica in realtà tradotto in IL?

È stato utile?

Soluzione

Funziona in modo simile alla parola yield return in C # 2.0.

:

Un metodo asincrono non è in realtà un metodo sequenziale ordinario. Viene compilato in una macchina a stati (un oggetto) con uno stato (variabili locali vengono trasformati in campi dell'oggetto). Ogni blocco di codice tra due utilizzi di await è uno "step" della macchina a stati.

Ciò significa che quando il metodo avvia, si esegue semplicemente il primo passo e poi la macchina dello Stato rendimenti e gli orari un po 'di lavoro da fare - quando il lavoro è fatto, verrà eseguito il prossimo passo della macchina statale. Per esempio questo codice:

async Task Demo() { 
  var v1 = foo();
  var v2 = await bar();
  more(v1, v2);
}

sarebbe tradotto in qualcosa di simile:

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 è che semplicemente utilizza il metodo SetContinuation per specificare che quando il completamento del servizio, dovrà chiamare di nuovo il metodo Step (e il metodo sa che deve eseguire il secondo bit del codice originale utilizzando il campo _state) . Si può facilmente immaginare che la SetContinuation sarebbe qualcosa di simile btn.Click += Step, che sarebbe in tutto su un singolo thread.

Il modello di programmazione asincrona in C # è molto vicino a F # workflow asincroni (in realtà, è essenzialmente la stessa cosa, a parte alcuni dettagli tecnici), e la scrittura reattivi applicazioni GUI single-threaded con async è una zona molto interessante - almeno io la penso così - vedi ad esempio questo articolo (forse dovrei scrivere una versione C # ora: -))

.

La traduzione è simile a iteratori (e yield return) e in effetti, è stato possibile utilizzare iteratori per implementare la programmazione asincrona in C # in precedenza. Ho scritto un articolo su che qualche tempo fa - e penso che può ancora dare qualche comprensione su come funziona la traduzione.

Altri suggerimenti

  

Come posso avere un intervento eseguito in parallelo sullo stesso thread?

Non è possibile. Asynchrony non è "parallelismo" o "concorrenza" . Asincronia potrebbe essere implementato con il parallelismo, o potrebbe non essere. Potrebbe essere implementata da spezzare il lavoro in piccoli pezzi, mettendo ogni pezzo di lavoro su una coda e quindi l'esecuzione di ogni pezzo di lavoro ogni volta che il filo sembra essere non fare niente altro.

Ho una serie di articoli nel mio blog su come funziona tutta questa roba; quello direttamente attinente a questa domanda sarà probabilmente salire Giovedi della prossima settimana. Guarda

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

per i dettagli.

Da quanto ho capito, quello che il async e le parole chiave await fanno è che ogni volta che un metodo async impiega la parola chiave await, il compilatore girare il resto del metodo in una continuazione che è prevista quando l'operazione asincrona viene completata. Che permette metodi async per tornare al chiamante immediatamente e riprendere il lavoro quando la parte asincrona è fatto.

:

Secondo i giornali disponibili ci sono un sacco dettagli ad esso, ma se non mi sbaglio, che è l'essenza di esso.

Per come la vedo lo scopo dei metodi asincroni non è quello di eseguire un sacco di codice in parallelo, ma per tritare asincrona metodi in un certo numero di piccoli pezzi, che può essere chiamato, se necessario. Il punto chiave è che il compilatore di gestire tutto il complesso cablaggio della callback utilizzando compiti / continuazioni. Questo non solo riduce la complessità, ma permette metodo asincrono da scrivere più o meno come il codice sincrono tradizionali.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top