为什么在异步方法中返回Task.CompletedTask失败了编译?

4

我正在使用VS2019和dotnetcore 3.1来创建一个简单的控制台应用程序,以下是我的代码片段:

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

它无法编译。我只想创建一个既是异步的(1),又返回一个任务(2)的方法。为什么这个返回语句不能编译?如何修复它以满足我的要求(1)和(2)?

非常感谢。


3
当您需要返回任务并且不使用async/await时,应仅使用Task.CompletedTask - juharr
3个回答

7
你的方法可以这样简化成一个功能:
public static Task F() 
{ 
  return Task.Delay(1000); 
}

只有在以下情况下返回Task.CompletedTask实例才有用:

  • 您不想使用async/await
  • 您的方法返回一个Task(如果您不将其异步化,则有效地等同于void
  • 您的代码具有任务可能未返回的逻辑

示例:

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

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

一旦您将方法标记为async,实际返回的 Task 被抽象化了。这样可以使代码更易于处理,特别是在有多个等待 I/O 操作完成的点时。

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
}

我还建议您查阅以下先前的问题:


5

await Task.Delay(1000); 方法已经创建并返回了一个 Task,因此您可以这样写:

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

或使用 awaitTask.CompletedTask; 一起使用。

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

否则,您应该将返回类型更新为Task<Task>,这没有太多意义。
public static async Task<Task> F()
{
    await Task.Delay(1000);
    return Task.CompletedTask;
}

2
它无法编译。我只想创建一个既是(1)异步的,又返回(2)任务的方法。为什么这个返回语句不能被编译?如何修复以满足我的(1)和(2)要求? “async”关键字将指示编译器创建状态机,而该状态机的工作是创建从此方法返回的“Task”。因此,如果您使用“async”,则不需要返回“Task”:请参阅此处
public static async Task F()
{
  await Task.Delay(1000);
  return;
}

或者等价地说:
public static async Task F()
{
  await Task.Delay(1000);
}

异步状态机和任务返回的解释非常好。 - Troskyvs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接