Nous avons cette méthode:
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
string urlContents = await getStringTask;
//The thing is that this returns an int to a method that has a return type of Task<int>
return urlContents.Length;
}
Une conversion implicite se produit-elle entre Task<int>
et int
? Sinon, que se passe-t-il? Comment cela fonctionne-t-il?
async
mot clé.Réponses:
Nan. C'est juste une partie de la façon dont
async
/await
fonctionne.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 / d'échec)Task<T>
(pour un résultat logique de typeT
de manière asynchrone)Le compilateur effectue tout l'encapsulation appropriée. Le fait est que vous retournez de manière asynchrone
urlContents.Length
- vous ne pouvez pas simplement renvoyer la méthodeint
, car la méthode réelle retournera lorsqu'elle atteindra la premièreawait
expression qui n'est pas déjà terminée. Donc, à la place, il retourne unTask<int>
qui se terminera lorsque la méthode async elle-même sera terminée.Notez que cela
await
fait le contraire - il déroule aTask<T>
en uneT
valeur, c'est ainsi que cette ligne fonctionne:... mais bien sûr, il le déballe de manière asynchrone, alors que le simple fait d'utiliser
Result
le bloquerait jusqu'à ce que la tâche soit terminée. (await
peut dérouler d'autres types qui implémentent le modèle attendu, maisTask<T>
c'est celui que vous utiliserez probablement le plus souvent.)Ce double emballage / déballage est ce qui permet à async d'être aussi composable. Par exemple, je pourrais écrire une autre méthode asynchrone qui appelle la vôtre et double le résultat:
(Ou tout simplement
return await AccessTheWebAsync() * 2;
bien sûr.)la source
async
/await
et je trouve cela extrêmement peu intuitif. IMO, il devrait y avoir un mot-clé ou similaire à lareturn
pour que cela soit clair, par exemplereturn async result;
(de la même manière queawait result
"déballe" leT
deTast<T>
).await
- avecT foo = someTaskT;
vous obtiendrez "Impossible de convertir implicitement le typeTask<T>
enT
" - de la même manière que je soutiens qu'il serait plus logique d'avoir un mot clé pour l'inverse (encapsulationTask<T>
). Je suis tout à fait pour supprimer les peluches, mais dans ce cas, je pense que cela fournit une obfuscation inutile dans lesasync
méthodes. (Évidemment, le point est discutable car les pouvoirs en place ont déjà parlé / codé!)async
, je pense que cela suffit.No nécessite la conversion de la tâche en int. Utilisez simplement le résultat de la tâche.
Il retournera la valeur si disponible, sinon il retournera 0.
la source
Result
; cela peut provoquer des blocages! Considérez par exemple ce flux de travail: (1) Écrivez une note qui dit "tondre la pelouse". (2) Attendez que la pelouse soit tondue (3) Mangez un sandwich, (4) Faites ce qu'il dit sur la note ". Avec ce flux de travail, vous ne mangez jamais un sandwich ou ne tondez jamais la pelouse, car l'étape 2 est une attente synchrone sur quelque chose que vous ferez à l'avenir . Mais c'est le flux de travail que vous décrivez ici.