Czy niejawna konwersja występuje między Task <> i int?
Nie. To tylko część tego, jak async
/ await
działa.
Każda metoda zadeklarowana jako async
musi mieć zwracany typ:
void
(unikaj, jeśli to możliwe)
Task
(brak wyniku poza powiadomieniem o zakończeniu / niepowodzeniu)
Task<T>
(dla logicznego wyniku typu T
w sposób asynchroniczny)
Kompilator wykonuje wszystkie odpowiednie opakowania. Chodzi o to, że jesteś asynchronicznie powrocie urlContents.Length
- nie może sprawić, że metoda po prostu wrócić int
, jak rzeczywista metoda zwróci gdy trafi pierwszy await
wyraz, który nie został już ukończony. Zamiast tego zwraca wartość, Task<int>
która zakończy się po zakończeniu samej metody asynchronicznej.
Zauważ, że await
robi to odwrotnie - rozpakowuje a Task<T>
do T
wartości, tak jak działa ta linia:
string urlContents = await getStringTask;
... ale oczywiście rozpakowuje je asynchronicznie, podczas gdy samo użycie Result
spowoduje zablokowanie do zakończenia zadania. ( await
może rozpakować inne typy, które implementują oczekiwany wzorzec, ale Task<T>
jest to ten, którego prawdopodobnie będziesz używać najczęściej).
To podwójne zawijanie / rozpakowywanie umożliwia komponowanie asynchronii. Na przykład mógłbym napisać inną metodę asynchroniczną, która wywoła Twoją i podwaja wynik:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(Lub po prostu return await AccessTheWebAsync() * 2;
oczywiście.)
async
słowa kluczowego.