2014-09-08 26 views
11

Chcę utworzyć żądanie usługi sieciowej asynchron. Ja nazywam go tutaj:Lista zwrotów z metody async/await

List<Item> list = GetListAsync(); 

Oto deklaracja mojej funkcji, które powinny zwrócić listę:

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

Jeśli chcę skompilować otrzymuję następujący błąd

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

Jak wiem Jeśli używam modyfikatora async, wynik jest automatycznie pakowany w Zadanie. Myślę, że tak się nie dzieje, ponieważ używam Task.Run. Jeśli usunąć Task.Run(() => część dostaję

Nie można oczekiwać System.Collections.Generic.List wyraz

Chyba nie zrozumiałeś asynchronicznie/czekają metod. Co robię źle?

+0

możliwe duplikat [Nie można niejawnie przekonwertować typu z Task <>] (http: // stackoverflow. com/questions/12886559/nie można-niejawnie konwertować-typu-z-zadania) – i3arnon

Odpowiedz

27

Musisz poprawić swój kod czekać na listy, aby pobrać:

List<Item> list = await GetListAsync(); 

Ponadto, upewnij się, że sposób, w którym znajduje się ten kod, ma async modyfikatora.

Powodem, dla którego pojawia się ten błąd, jest to, że metoda GetListAsync zwraca wartość Task<T>, która nie jest wynikiem zakończonym. Ponieważ Twoja lista jest pobierana asynchronicznie (z powodu Task.Run()), musisz "wyodrębnić" wartość z zadania, używając słowa kluczowego await.

Jeśli usuniesz Task.Run(), to lista będzie pobierany synchronicznie i nie trzeba używać Task, async lub await.

Jeszcze jedna sugestia: nie trzeba czekać w GetListAsync metody jeśli jedyną rzeczą, jaką można zrobić, to po prostu delegowania operację do innego wątku, więc można skrócić kod do następującego:

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

Będą również musiały upewnić się, że metoda wywołująca ten kod jest wykonana metodą "asynchroniczną" (jeśli jeszcze tego nie zrobiono). –

+0

Czego nie dostaję, to dlaczego muszę "czekać" dwa razy? – testing

+0

@ testowanie, musisz czekać dwa razy, ponieważ masz 2 asynchroniczne wywołania –

7

Oprócz odpowiedzi @ takemyoxygen konwencja o nazwie funkcji, która kończy się Async, jest prawdziwie asynchroniczna. To znaczy. nie uruchamia nowego wątku i nie po prostu wywołuje Task.Run. Jeśli tak jest cały kod, który jest w swojej funkcji, to będzie lepiej, aby go usunąć całkowicie i po prostu:

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

Mam również blok try/catch, aby wychwycić wyjątki i pokazuję spinnera . Tak więc moja nazwa metody jest poprawna niż? – testing

+0

Tak, myślę, że powinno być OK, zaczynanie nowego wątku nie jest idealne, ale myślę, że wytyczna jest bardziej o wywoływanie synchronicznej wersji funkcji wewnątrz 'Task.Run' –

Powiązane problemy