Elenco<MyObject> non contiene una definizione per GetAwaiter

Ho un metodo che restituisce un Elenco<> di un oggetto. Questo metodo richiede più tempo per l’esecuzione.

private List<MyObject> GetBigList()
{
    ... slow stuff
}

Questo metodo viene chiamato da 4 o 5 fonti. Così, ho pensato di provare ad utilizzare il async e await per mantenere le cose in movimento, mentre questo elenco costruisce. Ho aggiunto questo metodo:

public async Task<List<MyObject>> GetBigListAsync()
{
    var resultsTask = GetBigList();
    var resuls = await resultsTask;
    return resuls;
}

Ma, su questa linea:

var resuls = await resultsTask;

Ottengo questo errore:

Elenco<MyObject> non contiene una definizione per GetAwaiter,
e alcun metodo di estensione ‘GetAwaiter’ accettazione di un primo argomento di tipo List<MyObject> potrebbe essere trovato.

Che cosa mi manca?

Il codice di esempio non mostra alcun uso di un Compito in GetBigList metodo né è contrassegnato come async, e questo significa che il risultato di tale metodo non può essere atteso.
provare async Task<Elenco<MyObject>> GetBigList()
Ricordate, attendono di non fare un’operazione sincrona in un’operazione asincrona. Attendono segni per il resto dell’attuale metodo di come la continuazione di un già esistente operazione asincrona. Attesa sul gestione asincronia, non creazione. Se si desidera un funzionamento sincrono di essere asincrona, si sta andando ad avere per capire un modo per fare che questo accada.

OriginaleL’autore Casey Crookston | 2016-11-23

2 Replies
  1. 19

    Sembra un newbee a async-attendono. La cosa che davvero mi ha aiutato a capire che cosa async-attendono non è il ristorante analogia dato da Eric Lippert in questa intervista. di Ricerca da qualche parte nel mezzo per async attendono.

    Qui egli descrive che se un cuoco deve aspettare qualcosa, invece di fare niente che lui inizia a guardare intorno per vedere se si può fare qualcos’altro nel frattempo.

    Async-attendono è simile. Invece di attesa per un file da leggere, una query di database per il ritorno, una pagina web per essere scaricato, il thread va fino allo stack di chiamate per vedere se uno qualsiasi dei chiamanti non sono in attesa ed esegue queste istruzioni fino a che non vede un attendono. Una volta vede la attendono il filo va lo stack di chiamate per vedere se uno dei chiamanti non è in attesa, etc. Dopo un po ‘ quando il file viene letto, o la query è finito ecc, le dichiarazioni dopo la attendono vengono eseguite.

    Normalmente durante la lettura del tuo grande lista il tuo thread sarebbe molto occupato, invece di guardare in attesa. Non è certo che l’ordinazione di un altro thread per fare le cose potrebbero migliorare il tempo necessario per leggere la vostra lista. Prendere in considerazione la misurazione di entrambi i metodi.

    Una ragione per usare la async-attendono, anche se si allungano i tempi
    per leggere l’elenco di grandi dimensioni, potrebbe essere quello di tenere il chiamante (utente
    interfaccia?) reattivo.

    Per rendere la vostra funzione asincrona, si deve procedere come segue:

    • Dichiarare la funzione asincrona;
    • Invece di TResult ritorno Task<TResult> e invece di void ritorno Task;
    • Se la funzione chiamate di altri async funzioni, in considerazione ricordando attività restituita invece di await, fare altre cose utili e che await il compito quando è necessario il risultato;
    • Se si vuole veramente lasciare un altro thread occupato roba. chiamata

      Attività.Run( () => GetBigList())

    e attendono quando avete bisogno di risultati.

    private async Task<List<MyObject>> GetBigListAsync()
    {
        var myTask = Task.Run( () => GetBigList());
        //your thread is free to do other useful stuff right nw
        DoOtherUsefulStuff();
        //after a while you need the result, await for myTask:
        List<MyObject> result = await myTask;
    
        //you can now use the results of loading:
        ProcessResult(result);
        return result;
    }

    Ancora una volta: se non hai niente di utile da fare, mentre l’altro thread è il caricamento della Lista (come talmente semplice mantenere aggiornati i UI responsive), non fare questo, o almeno misurare se sono più veloci.

    Altri articoli che mi hanno aiutato a capire async-attendono erano
    Async attendono, da sempre così disponibile Stephen Cleary,
    – e un po ‘ più avanzato: Async-Attendere le migliori pratiche.

    OriginaleL’autore Harald Coppoolse

  2. 12

    resultTask è solo la lista restituita da GetBigList(), così non succederà nulla async c’.

    Cosa si può fare è trasferire l’attività in un thread separato il threadpool utilizzando Task.Run e restituire il awaitable Task oggetto:

    //Bad code
    public Task<List<MyObject>> GetBigListAsync()
    {
        return Task.Run(() => GetBigList());
    }

    Mentre sopra di esempio migliore corrisponde a ciò che si sta tentando di fare, non è la prassi migliore. Provate a fare il GetBigList() async dalla natura o se davvero non c’è modo, lasciare la decisione sull’esecuzione di codice in un thread separato per il codice chiamante e non nascondere questo in attuazione F. e. se il codice chiamante è già in esecuzione, async, non c’è motivo per deporre le uova, ma in un altro thread. Questo articolo descrive più in dettaglio.

    OriginaleL’autore huysentruitw

Lascia un commento