Uma conversão implícita ocorre entre Task <> e int?
Não. Isso é apenas parte de como async
/ await
funciona.
Qualquer método declarado como async
deve ter um tipo de retorno de:
void
(evite se possível)
Task
(nenhum resultado além da notificação de conclusão / falha)
Task<T>
(para um resultado lógico de tipo de T
maneira assíncrona)
O compilador faz todo o empacotamento apropriado. A questão é que você está retornando de forma assíncronaurlContents.Length
- você não pode fazer o método apenas retornar int
, pois o método real retornará quando atingir a primeira await
expressão que ainda não foi concluída. Em vez disso, ele retorna um Task<int>
que será concluído quando o próprio método assíncrono for concluído.
Observe que await
faz o oposto - ele desembrulha a Task<T>
em um T
valor, que é como esta linha funciona:
string urlContents = await getStringTask;
... mas é claro que ele desembrulha de forma assíncrona, ao passo que apenas o uso Result
bloquearia até que a tarefa fosse concluída. ( await
pode desembrulhar outros tipos que implementam o padrão aguardado, mas Task<T>
é aquele que você provavelmente usará com mais frequência.)
Esse empacotamento / desembrulhamento duplo é o que permite que o assíncrono seja tão combinável. Por exemplo, eu poderia escrever outro método assíncrono que chama o seu e duplica o resultado:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(Ou simplesmente, é return await AccessTheWebAsync() * 2;
claro.)
async
palavra - chave.