Чи відбувається неявна конверсія між Task <> та int?
Ні. Це лише частина того, як async/ awaitпрацює.
Будь-який метод, оголошений як asyncповинен мати тип повернення:
void (уникайте, якщо можливо)
Task (ніякого результату після повідомлення про завершення / відмову)
Task<T>(для логічного результату введення Tасинхронним способом)
Компілятор робить усі необхідні обгортання. Справа в тому, що ви асинхронно повертаєтесь urlContents.Length- ви не можете змусити метод просто повернутися int, оскільки власне метод повернеться, коли він потрапить у перший awaitвираз, який ще не завершився. Отже, замість цього він повертає a, Task<int>який завершиться після завершення самого методу асинхронізації.
Зверніть увагу , що awaitробить протилежне - він розгортаєTask<T> до Tвартості, яка , як працює цей рядок:
string urlContents = await getStringTask;
... але, звичайно, він розгортає його асинхронно, тоді як просто використання Resultблокує, поки завдання не буде виконано. ( awaitможе розгортати інші типи, які реалізують очікувану схему, але Task<T>саме ви, ймовірно, використовуєте найчастіше.)
Це подвійне обгортання / розгортання - це те, що дозволяє асинхронізації бути такою композиційною. Наприклад, я можу написати інший метод асинхронізації, який викликає ваш і подвоює результат:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(Або просто return await AccessTheWebAsync() * 2;звичайно.)
asyncключового слова.