Y a-t-il une conversion implicite entre Task<> et int ?
Nope. C'est juste une partie de la façon dont async
/ await
travaux.
Toute méthode déclarée comme async
doit avoir un type de retour de :
-
void
(à éviter si possible)
-
Task
(aucun résultat au-delà de la notification d'achèvement/échec)
-
Task<T>
(pour un résultat logique de type T
de manière asynchrone)
Le compilateur se charge de l'habillage approprié. Le fait est que vous de manière asynchrone en retournant sur urlContents.Length
- vous ne pouvez pas faire en sorte que la méthode renvoie simplement int
car la méthode actuelle retournera lorsqu'elle atteindra le premier élément de la liste. await
qui n'est pas encore terminée. Donc, à la place, il renvoie un Task<int>
qui se terminera lorsque la méthode asynchrone elle-même se terminera.
Notez que await
fait le contraire - il déballer a Task<T>
à un T
c'est ainsi que cette ligne fonctionne :
string urlContents = await getStringTask;
... mais bien sûr, il le déballe de manière asynchrone, alors que l'utilisation de l'option Result
bloquerait jusqu'à ce que la tâche soit terminée. ( await
peut déballer d'autres types qui implémentent le modèle awaitable, mais Task<T>
est celui que vous utiliserez probablement le plus souvent).
Ce double enveloppement/désemballage est ce qui permet à l'asynchronisme d'être si composable. Par exemple, je pourrais écrire une autre méthode asynchrone qui appelle la vôtre et double le résultat :
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(Ou simplement return await AccessTheWebAsync() * 2;
bien sûr.)