Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why returning Task.CompletedTask failed to compile in an async method?

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.

like image 737
Troskyvs Avatar asked Oct 23 '25 14:10

Troskyvs


2 Answers

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:

  • How and when to use ‘async’ and ‘await’
  • Understanding async / await in C#
like image 69
Igor Avatar answered Oct 27 '25 02:10

Igor


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;
}
like image 35
Pavel Anikhouski Avatar answered Oct 27 '25 00:10

Pavel Anikhouski