2016-05-02 19 views
5

Ho il seguente metodo che impegna le modifiche a un db (utilizzando Entity Framework):Effetti dell'utilizzo di più attese nello stesso metodo?

public async Task<int> CommitAsync(Info info) 
{ 
    if (this.Database.Connection.State == ConnectionState.Closed) 
     await this.Database.Connection.OpenAsync(); 

    await SetInfo(info); 
    return await base.SaveChangesAsync(); 
} 

è sicuro da usare come è il metodo di cui sopra, o dovrei:

  1. Evitare di utilizzare async-await, o
  2. Usa ContinueWith

risposta

12

e 'assolutamente bene avere più await espres ssioni nello stesso metodo async - altrimenti sarebbe una funzione relativamente inutile.

Fondamentalmente, il metodo verrà eseguito in modo sincrono finché non raggiunge il primo await dove l'attendibile coinvolto non è ancora stato completato. Verrà quindi restituito al chiamante, dopo aver impostato una continuazione per l'attendibile per eseguire il resto del metodo asincrono. Se l'esecuzione successiva raggiunge un altro await espressione dove l'awaitable non ha già completato, una continuazione è impostato su che awaitable, ecc

Ogni volta che il metodo "riprende" da un attendono, essa esercita in cui era stata spento, con le stesse variabili locali ecc. Ciò è ottenuto dal compilatore che costruisce una macchina di stato per conto dell'utente.

+0

La mia comprensione è corretta? Se abbiamo due attese, il codice dopo la seconda attesa sarebbe solo la continuazione per la seconda attesa, non per la prima attesa Se non fosse il caso, il codice dopo la seconda attesa sarebbe stato eseguito due volte (prima, come continuazione alla prima Attendibile e secondo come continuazione del secondo attendente – YakRangi

+0

@Rouftantical: Sì, come ho detto "procede da dove era stato interrotto". –

2

Il tuo codice sembra perfetto. Dà al tuo interlocutore l'opportunità di fare qualcosa di utile nei momenti che stai aspettando, invece di fare un'attesa impegnativa finché tutto è finito.

La cosa bella di usare async-await invece di usare ContinueWith è che il tuo codice sembra abbastanza sincrono. È facile vedere in quale ordine verranno eseguite le dichiarazioni. Continua Con consente inoltre di specificare l'ordine, ma è un po 'più difficile da vedere.

Se un thread entra in una procedura asincrona esegue la procedura fino a quando non soddisfa un'attesa. Invece di aspettare fino a quando la procedura attesa è finita, il controllo viene restituito al chiamante che può continuare a eseguire le istruzioni successive fino a quando non incontra un'attesa, dove viene dato il controllo al chiamante ecc. Una volta che tutti sono in attesa e il tuo OpenAsync è finito il thread continua a fare le dichiarazioni dopo OpenAsync fino a quando non incontra un'altra attesa.

Qualcuno qui in StackOverflow (ahimè ha perso il suo nome) mi ha spiegato una volta che il processo async-await in un breakfast metaphor.

Un'introduzione molto utile, Stephen Cleary about Async-await. Ti rendiamo conto anche di come async-await previene i problemi con InvokeRequired

+1

Penso che la metafora della colazione sia iniziata con Eric Lippert. Ecco un link ad alcune parti di http://www.i-programmer.info/professional-programmer/i-programmer/7154-c-guru-an-interview-with-eric-lippert.html?start=1 Ho seguito entrambi gli Skeet , Cleary e Lippert come un falco negli ultimi anni o giù di lì. Assicurati di leggere anche sulla metafora della ciotola di frutta e gabbie per animali. – Zuzlx