Происходит ли неявное преобразование между Task <> и int?
Нет. Это всего лишь часть того, как async
/ await
работает.
Любой метод, объявленный как, async
должен иметь возвращаемый тип:
void
(по возможности избегайте)
Task
(нет результата, кроме уведомления о завершении / неудаче)
Task<T>
(для логического результата типа T
асинхронно)
Компилятор выполняет все необходимые обертывания. Дело в том, что вы возвращаетесь асинхронноurlContents.Length
- вы не можете заставить метод просто возвращаться int
, поскольку фактический метод вернется, когда он попадет в первое await
выражение, которое еще не завершено. Поэтому вместо этого он возвращает, Task<int>
который завершится, когда завершится сам асинхронный метод.
Обратите внимание, что await
происходит обратное - он разворачивает a Task<T>
в T
значение, как работает эта строка:
string urlContents = await getStringTask;
... но, конечно, он разворачивает его асинхронно, тогда как простое использование Result
блокирует его до тех пор, пока задача не будет завершена. ( await
может разворачивать другие типы, реализующие ожидаемый шаблон, но Task<T>
это тот, который вы, вероятно, будете использовать чаще всего.)
Эта двойная упаковка / развертывание - это то, что позволяет async быть настолько компонуемым. Например, я мог бы написать еще один асинхронный метод, который вызывает ваш и удваивает результат:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(Или просто return await AccessTheWebAsync() * 2;
конечно.)
async
ключевого слова.