2014-09-08 8 views
11

Ich möchte eine Webservice-Anfrage asynchron machen. Ich nenne es hier:Rückgabeliste von async/await-Methode

List<Item> list = GetListAsync(); 

Hier die Erklärung meiner Funktion ist, die eine Liste zurückgeben soll:

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

Wenn ich bekomme ich folgende Fehler kompilieren wollen

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

Wie ich weiß Wenn ich den Modifikator async verwende, wird das Ergebnis automatisch mit Task umschlossen. Ich denke, das passiert nicht, weil ich Task.Run verwende. Wenn ich den Task.Run(() => Teil entfernen bekomme ich

nicht System.Collections.Generic.List Ausdruck

erwarten Kann ich glaube, ich habe nicht in vollem Umfang von der Asynchron verstanden/erwarten Methoden. Was mache ich falsch?

+0

möglich Duplikat [Kann nicht implizit Art von Aufgabe konvertieren <>] (http: // Stackoverflow. com/questions/12886559/can-implizit-convert-type-from-task) – i3arnon

Antwort

27

Sie müssen Ihren Code korrigieren, um die Liste zu warten heruntergeladen werden:

List<Item> list = await GetListAsync(); 

Stellen Sie außerdem sicher, dass das Verfahren, in dem dieser Code befindet, async Modifikator hat.

Der Grund, warum diese Fehlermeldung erhalten, dass GetListAsync Methode eine Task<T> gibt, die kein abgeschlossenes Ergebnis. Wenn Ihre Liste asynchron heruntergeladen wird (wegen Task.Run()), müssen Sie den Wert aus der Aufgabe mit dem Schlüsselwort await "extrahieren".

Wenn Sie entfernen Task.Run(), listen Sie synchron heruntergeladen werden und Sie brauchen nicht Task, async oder await zu verwenden.

Ein weiterer Vorschlag: Sie brauchen nicht in GetListAsync Verfahren erwarten, wenn das einzige, was Sie gerade tun, um den Betrieb zu einem anderen Thread zu delegieren, so können Sie Ihren Code wie folgt verkürzen:

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

Sie müssen auch sicherstellen, dass die Methode, die diesen Code aufruft, zu einer 'async'-Methode gemacht wird (falls nicht schon). –

+0

Was ich nicht verstehe, warum muss ich zweimal "warten"? – testing

+0

@test, müssen Sie zweimal warten, weil Sie 2 async Anrufe haben –

7

Zusätzlich zu @ takemyoxygens Antwort lautet die Konvention, einen Funktionsnamen zu haben, der in Async endet, dass diese Funktion wirklich asynchron ist. I.e. Es startet keinen neuen Thread und ruft nicht einfach Task.Run auf. Wenn das alles des Code ist, die in Ihrer Funktion ist, wird es besser sein, es vollständig zu entfernen und einfach hat:

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

Ich habe auch einen Versuch/catch-Block, um die Ausnahmen zu fangen, und ich zeige einen Spinner . Also ist mein Methodenname korrekt als? – testing

+0

Ja ich denke, es sollte in Ordnung sein, ein neuer Thread zu starten ist nicht ideal, aber ich denke, die Richtlinie ist mehr über das Aufrufen einer synchronen Version der Funktion in 'Task.Run' –

Verwandte Themen