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?
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());
}
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());
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.