4

I'm using VS2019 and dotnetcore 3.1 for a simple console application, I've this code piece:

public static async Task F()
{
    await Task.Delay(1000);
    return Task.CompletedTask; // error
}

It doesn't compile. I just with to create a method that is (1) async, and (2) returns a Task. Why this return statement doesn't compile? How to fix it to fulfill my requirement of (1) and (2)?

Thanks a lot.

Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • 3
    You should only use `Task.CompletedTask` when you need to return a task and you're not using async/await. – juharr Mar 05 '20 at 19:19

3 Answers3

7

Your method could functionally be condensed down to this.

public static Task F() 
{ 
  return Task.Delay(1000); 
}

Returning an Task.CompletedTask instance is only useful if these apply:

  • you do not want to use async/await
  • your method returns a Task (effectively void if you were to make it not asynchronous)
  • your code has logic where a task might not be returned

Example:

public static Task F() 
{ 
  if (someConditionToShortCircutTheMethod) 
      return Task.CompletedTask;

  // rest of logic
  return Task.Delay(1000); 
}

As soon as you make your method async then the fact that a Task is actually being returned is abstracted. This can make the code easier to work with especially if there are multiple points where the code waits for I/O operations to complete.

public static async Task F() 
{ 
  if (someConditionToShortCircutTheMethod) 
      return;

  // rest of logic
  await Task.Delay(1000); 
  await Task.Delay(1000);
  // no return necessary, async Task has a similar flow as return type void
}

I also recommend reviewing these previous questions:

Igor
  • 60,821
  • 10
  • 100
  • 175
5

await Task.Delay(1000); method already creates and returns a Task, so you could write

public static async Task F()
{
    await Task.Delay(1000);
}

Or use await with Task.CompletedTask;

public static async Task F()
{
    await Task.Delay(1000);
    await Task.CompletedTask;
}

Otherwise you should update return type to Task<Task>, which doesn't make a lot of sense

public static async Task<Task> F()
{
    await Task.Delay(1000);
    return Task.CompletedTask;
}
Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
2

It doesn't compile. I just with to create a method that is (1) async, and (2) returns a Task. Why this return statement doesn't compile? How to fix it to fulfill my requirement of (1) and (2)?

The async keyword will instruct the compiler to create a state machine, and it is the job of that state machine to create the Task returned from this method. So you don't need to return a Task if you're using async:

public static async Task F()
{
  await Task.Delay(1000);
  return;
}

or equivalently:

public static async Task F()
{
  await Task.Delay(1000);
}
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810