Чи відбувається неявна конверсія між 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
ключового слова.