What do I return from a method that returns just Task and not Task<T>?

18,533

Solution 1

You can think of async as constructing a Task wrapper for you. If you don't use async, then you can return an actual Task object.

Your first code example is using async but then you try to return a Task. Returning a Task isn't necessary with async:

async static Task D4()
{
  Console.Write("Enter the divisor: ");
  var n = int.Parse(Console.ReadLine());
  Console.WriteLine((24 / n).ToString());

  return; // May be removed, since it is implicit.
}

Your second code example removed the async and then tries to not return anything; in this case, since async isn't creating a Task for you, you need to create one yourself:

static Task D4()
{
  Console.Write("Enter the divisor: ");
  var n = int.Parse(Console.ReadLine());
  Console.WriteLine((24 / n).ToString());

  return Task.FromResult(0);
}

The first example (where async creates the Task for you) is more idiomatic. Note that you should also be using an await in the async method.

Solution 2

Remove the async keyword so it becomes

static Task D4()
{
    return Task.FromResult(0); // or one of the others from your post
}

You don't need to await a Task.FromResult(). Even if you would use a Task that does actual work using Task.Run() as the last part of the method. See Awaiting tasks: Return task or await if no code after await

Share:
18,533
Water Cooler v2
Author by

Water Cooler v2

https://sathyaish.net/?c=pros https://www.youtube.com/user/Sathyaish

Updated on June 05, 2022

Comments

  • Water Cooler v2
    Water Cooler v2 over 1 year

    What do I return from D4()?

    async static Task D4()
    {
        Console.Write("Enter the divisor: ");
        var n = int.Parse(Console.ReadLine());
        Console.WriteLine((24 / n).ToString());
    
        // NONE OF THESE WORK
        // THE COMPILER COMPLAINS WITH AN ERROR THAT SAYS:
        // Since 'Program.D4()' is an async method that returns 'Task', 
        // a return keyword must not be followed by an object expression.
        // Did you intend to return 'Task<T>'?
        // return new TaskCompletionSource<object>().Task;
        // return Task.FromResult<object>(null);
        // return Task.FromResult<bool>(false);
        // return Task.FromResult(0);
    }
    

    I asked something similar earlier and it probably worked in my situation then but I have no recollection of the situation now. Also, this thread seems to suggest the same thing that I am trying. I am not sure why it doesn't work in my case.

    UPDATE

    For the sake of completeness, here is the whole of the relevant bit of code.

    async static Task A4() { await B4(); }
    async static Task B4() { await C4(); }
    async static Task C4() { await D4(); }
    async static Task D4()
    {
        Console.Write("Enter the divisor: ");
        var n = int.Parse(Console.ReadLine());
        Console.WriteLine((24 / n).ToString());
    
        // return new TaskCompletionSource<object>().Task;
        // return Task.FromResult<object>(null);
        // return Task.FromResult<bool>(false);
        // return Task.FromResult(0);
    }
    
  • Jon Skeet
    Jon Skeet over 7 years
    The latter part is incorrect. Basically, you should treat an async Task method as if it were a void method; plain return; statements are fine, but you can't return a value.
  • Peter Bons
    Peter Bons over 7 years
    My bad, 2nd option shouldn't return anything indeed
  • Jon Skeet
    Jon Skeet over 7 years
    There's no point in awaiting Task.FromResult though. As that's always a completed task, it'll reach the end of the method synchronously.
  • Peter Bons
    Peter Bons over 7 years
    Exactly, technically it compiles and works but I gather the actual implementation will be different so I outlined both possibilities
  • Jon Skeet
    Jon Skeet over 7 years
    I don't see why there's an "exactly" there - just remove the body of the second part entirely. You don't need to await anything.
  • Water Cooler v2
    Water Cooler v2 over 7 years
    'Program.D4()': not all code paths return a value
  • Yacoub Massad
    Yacoub Massad over 7 years
    Not all the methods that return Task, only the ones that have the async keyword.
  • Tarek
    Tarek over 7 years
    I stand corrected, you need to include async in the function deceleration
  • Lee
    Lee over 7 years
    This will return null which is probably not what callers will expect. Your question is about async methods while D4 is not marked async. You should be able to use Task.FromResult to return a completed task since Task<T> extends Task. If you make D4 async then you should not return a value.
  • Water Cooler v2
    Water Cooler v2 over 7 years
    @Lee Sorry, D4 was marked async earlier but I posted the updated code in the interm of trying out various recommendations. I must have removed the async keyword during then. I have updated the code in the question.
  • Lee
    Lee over 7 years
    Your updated async version of D4 compiles, although you should get a warning about making it async since it doesn't await anything.
  • Water Cooler v2
    Water Cooler v2 over 7 years
    Many thanks. I have been awake too long. If you don't use async, then you can return an actual Task object. That was that. I have really been awake too long.
  • nawfal
    nawfal over 3 years
    Remember today there is Task.CompletedTask.