web-dev-qa-db-fra.com

Liste de retour de la méthode async / wait

Je veux faire une demande de service Web asynchrone. Je l'appelle ici:

List<Item> list = GetListAsync();

Voici la déclaration de ma fonction, qui devrait retourner une liste:

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

Si je veux compiler, j'obtiens l'erreur suivante

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

Comme je le sais Si j'utilise le modificateur async, le résultat est automatiquement encapsulé avec Task. Je pense que cela ne se produit pas parce que j'utilise Task.Run. Si je supprime la partie Task.Run(() => j'obtiens

Ne peut pas attendre l'expression System.Collections.Generic.List

Je pense que je n'ai pas bien compris les méthodes async/attente. Qu'est-ce que je fais mal?

20
testing

Vous devez corriger votre code pour attendre que la liste soit téléchargée:

List<Item> list = await GetListAsync();

Assurez-vous également que la méthode, où se trouve ce code, possède le modificateur async.

La raison pour laquelle vous obtenez cette erreur est que la méthode GetListAsync renvoie un Task<T> Qui n'est pas un résultat terminé. Comme votre liste est téléchargée de manière asynchrone (en raison de Task.Run()), vous devez "extraire" la valeur de la tâche à l'aide du mot clé await.

Si vous supprimez Task.Run(), votre liste sera téléchargée de manière synchrone et vous n'avez pas besoin d'utiliser Task, async ou await.

Une autre suggestion: vous n'avez pas besoin d'attendre dans la méthode GetListAsync si la seule chose que vous faites est simplement de déléguer l'opération à un thread différent, vous pouvez donc raccourcir votre code comme suit:

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

En plus de la réponse de @ takemyoxygen, la convention d'avoir un nom de fonction se terminant par Async est que cette fonction est vraiment asynchrone. C'est à dire. il ne démarre pas un nouveau thread et il n'appelle pas simplement Task.Run. Si c'est tout le code qui est dans votre fonction, il vaudra mieux le supprimer complètement et avoir simplement:

List<Item> list = await Task.Run(() => manager.GetList());
10
Ned Stoyanov

Travaille pour moi:

List<Item> list = Task.Run(() => manager.GetList()).Result;

de cette façon, il n'est pas nécessaire de marquer la méthode avec async dans l'appel.

1
sergiokml