Czy niejawna konwersja występuje między Task <> i int?
Nie. To tylko część tego, jak async/ awaitdziała.
Każda metoda zadeklarowana jako asyncmusi 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 Tw 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 awaitwyraz, 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 awaitrobi to odwrotnie - rozpakowuje a Task<T>do Twartości, tak jak działa ta linia:
string urlContents = await getStringTask;
... ale oczywiście rozpakowuje je asynchronicznie, podczas gdy samo użycie Resultspowoduje zablokowanie do zakończenia zadania. ( awaitmoż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.)
asyncsłowa kluczowego.