150 votes

Comment Task<int> devient-il un int ?

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 a-t-elle lieu entre Task<int> y int ? Si non, alors que se passe-t-il ? Comment le système est-il mis en œuvre pour fonctionner ?

220voto

Jon Skeet Points 692016

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.)

17voto

Aniket Sharma Points 956

Non, il faut convertir la tâche en int. Il suffit d'utiliser le résultat de la tâche.

int taskResult = AccessTheWebAndDouble().Result;

public async Task<int> AccessTheWebAndDouble()
{
    int task = AccessTheWeb();
    return task;
}

Il renvoie la valeur si elle est disponible, sinon il renvoie 0.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X