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.