2014-09-08 4 views
11

Desidero effettuare una richiesta asincronica del servizio web. Io lo chiamo qui:Restituzione elenco dal metodo async/attendi

List<Item> list = GetListAsync(); 

Ecco la dichiarazione della mia funzione, che dovrebbe restituire un elenco:

private async Task<List<Item>> GetListAsync(){ 
    List<Item> list = await Task.Run(() => manager.GetList()); 
    return list; 
} 

Se voglio compilare ricevo il seguente errore

Cannot implicitely convert type System.Threading.Tasks.Task<System.Collections.Generic.List<Item>> to System.Collections.Generic.List<Item> 

Come so Se utilizzo il modificatore async, il risultato viene automaticamente associato a Task. Penso che questo non accada perché io uso Task.Run. Se rimuovo la parte Task.Run(() => ottengo

di non poter attendere l'espressione System.Collections.Generic.List

penso che non ho capito completamente l'async/attendere metodi. Cosa sto facendo di sbagliato?

+0

possibile duplicato del [Impossibile convertire implicitamente il tipo da Task <>] (http: // StackOverflow. it/questions/12886559/can not-implicitly-convert-type-from-task) – i3arnon

risposta

27

è necessario correggere il codice per attendere che l'elenco da scaricare:

List<Item> list = await GetListAsync(); 

Inoltre, assicurarsi che il metodo, in cui si trova questo codice, ha async modificatore.

Il motivo per cui viene visualizzato questo errore è che il metodo GetListAsync restituisce un valore Task<T> che non è un risultato completato. Poiché l'elenco viene scaricato in modo asincrono (a causa di Task.Run()), è necessario "estrarre" il valore dall'attività utilizzando la parola chiave await.

Se si rimuove Task.Run(), si elenco verrà scaricato in modo sincrono e non c'è bisogno di usare Task, async o await.

Un altro suggerimento: non c'è bisogno di aspettare in GetListAsync metodo se l'unica cosa che devi fare è solo delegando l'operazione per un thread diverso, in modo da poter ridurre il codice al seguente:

private Task<List<Item>> GetListAsync(){ 
    return Task.Run(() => manager.GetList()); 
} 
+0

Devono inoltre garantire che il metodo che chiama questo codice sia reso un metodo 'async' (se non lo hanno già fatto). –

+0

Quello che non capisco è perché devo "aspettare" due volte? – testing

+0

@testing, devi attendere due volte perché hai 2 chiamate asincrone –

7

Oltre alla risposta di @ takemyoxygen, la convenzione di avere un nome di funzione che termina con Async è che questa funzione è veramente asincrona. Cioè non inizia una nuova discussione e non chiama semplicemente Task.Run. Se questo è tutto il codice che si trova nella funzione, sarà meglio per rimuoverlo completamente e semplicemente:

List<Item> list = await Task.Run(() => manager.GetList()); 
+0

Ho anche un blocco try/catch per rilevare le eccezioni e sto mostrando uno spinner . Quindi il mio nome del metodo è corretto di? – testing

+0

sì, penso che dovrebbe essere OK, l'avvio di un nuovo thread non è l'ideale, ma penso che la linea guida sia più di chiamare una versione sincrona della funzione all'interno di 'Task.Run' –