In che modo Task diventa un int?

Abbiamo questo metodo.

async Task AccessTheWebAsync() { HttpClient client = new HttpClient(); Task 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 return urlContents.Length; } 

Esiste una conversione implicita tra Task e int? Se no allora cosa sta succedendo, come viene implementato per funzionare?

Esiste una conversione implicita tra Task <> e int?

No. Questo è solo parte di come funziona async / await .

Qualsiasi metodo dichiarato async deve avere un tipo restituito di:

  • void (evitare se ansible)
  • Task (nessun risultato oltre la notifica di completamento / fallimento)
  • Task (per un risultato logico di tipo T in modo asincrono)

Il compilatore esegue tutto il wrapping appropriato. Il punto è che stai restituendo in modo asincrono urlContents.Length – non puoi rendere il metodo solo return int , poiché il metodo effettivo tornerà quando raggiunge la prima espressione di await che non è ancora stata completata. Quindi, invece, restituisce un’attività Task che verrà completata quando il metodo asincrono stesso completerà.

Nota che await fa l’opposto – scava un’attività Task ad un valore T , che è come funziona questa linea:

 string urlContents = await getStringTask; 

… ma ovviamente lo scarta in modo asincrono, mentre solo l’utilizzo di Result bloccherebbe fino al completamento dell’attività. ( await puoi scartare altri tipi che implementano il modello attendibile, ma l’ Task è quella che probabilmente utilizzerai più spesso).

Questo doppio wrapping / unwrapping è ciò che consente a async di essere così componibile. Ad esempio, potrei scrivere un altro metodo asincrono che chiama il tuo e raddoppia il risultato:

 public async Task AccessTheWebAndDouble() { var task = AccessTheWeb(); int result = await task; return result * 2; } 

(O semplicemente return await AccessTheWeb() * 2; ovviamente.)

No richiede la conversione di Task in int. Basta usare il risultato dell’attività.

 int taskResult= AccessTheWebAndDouble.Result; public async Task AccessTheWebAndDouble() { int task = AccessTheWeb(); return task; } 

Restituirà il valore se disponibile altrimenti restituirà 0.