Uma conversão implícita ocorre entre Task <> e int?
Não. Isso é apenas parte de como async/ awaitfunciona.
Qualquer método declarado como asyncdeve 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 Tmaneira 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 awaitexpressã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 awaitfaz o oposto - ele desembrulha a Task<T>em um Tvalor, que é como esta linha funciona:
string urlContents = await getStringTask;
... mas é claro que ele desembrulha de forma assíncrona, ao passo que apenas o uso Resultbloquearia até que a tarefa fosse concluída. ( awaitpode 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.)
asyncpalavra - chave.