Does an implicit conversion occur between Task<> and int?
Nope. This is just part of how async/await works.
Any method declared as async has to have a return type of:
void (avoid if possible)
Task (no result beyond notification of completion/failure)
Task<T> (for a logical result of type T in an async manner)
The compiler does all the appropriate wrapping. The point is that you're asynchronously returning urlContents.Length - you can't make the method just return int, as the actual method will return when it hits the first await expression which hasn't already completed. So instead, it returns a Task<int> which will complete when the async method itself completes.
Note that await does the opposite - it unwraps a Task<T> to a T value, which is how this line works:
string urlContents = await getStringTask;
... but of course it unwraps it asynchronously, whereas just using Result would block until the task had completed. (await can unwrap other types which implement the awaitable pattern, but Task<T> is the one you're likely to use most often.)
This dual wrapping/unwrapping is what allows async to be so composable. For example, I could write another async method which calls yours and doubles the result:
public async Task<int> AccessTheWebAndDoubleAsync()
{
var task = AccessTheWebAsync();
int result = await task;
return result * 2;
}
(Or simply return await AccessTheWebAsync() * 2; of course.)
asynckeyword.