Why does this async / await code generate "...not all code paths return a value"?

async-await, asynchronous, c#, c#-5.0, task-parallel-library

Solution

The non-generic `Task` type is somewhat equivalent to an awaitable void method. Just like a void method, you can't return anything from a method that has a return type of `Task`, which is why the first example compiles. The second example, though, expects a return value of the generic type and you aren't providing one in the path where you await another call.

Quoting from the MSDN reference on the `async` keyword, specifically about return types.

You use Task if no meaningful value is returned when the method is completed. That is, a call to the method returns a Task, but when the Task is completed, any await expression that's awaiting the Task evaluates to void.

Problem

Hopefully this isn't a repeat, but there are 5000+ questions here with "not all code paths return a value"! Quite simply, why does this method with a non-generic implementation compile just fine: ``` public static async Task TimeoutAfter(this Task task, int millisecondsTimeout) { if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout))) await task; else throw new TimeoutException(); } ``` while this attempt to make the method generic generates a `Return state missing` / ...`not all code paths return a value` warning / error?: ``` public static async Task<T> TimeoutAfter<T>(this Task<T> task, int millisecondsTimeout) { if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout))) await task; else throw new TimeoutException(); } ```

Original source