什么都不做的异步方法

时间:2013-05-13 15:36:31

标签: c# .net asynchronous async-await task

我有一个接口IAnimation,它公开了一个方法BeginAsync()。该方法应该启动动画并在完成时返回。

我想要做的是实现一个null动画类NoAnimation,它只在执行BeginAsync()时返回。

这是正确的实施吗?

public async Task BeginAsync()
{
    await Task.Run(() => { });
}

我怀疑有一种比这更优雅的方法。我也考虑过了 创建一个空方法。但这给了我一个我不喜欢的警告。

2 个答案:

答案 0 :(得分:19)

只需使用Task.CompletedTask即可返回已完成的任务:

public Task BeginAsync()
{
     return Task.CompletedTask;
}

如果您使用Task<TResult>使用Task.FromResult<TResult>来返回已完成的任务,结果为:

public Task<bool> BeginAsync()
{
     return Task.FromResult(true);
}

您当前的实现效率非常低,因为它构建状态机,并且还使用ThreadPool线程来运行空任务。

答案 1 :(得分:1)

很容易陷入async必须是任何异步方法签名的一部分的陷阱。看起来一定是;它(误导!)读取的目的似乎是将一个方法标记为异步。

但这不是必需的,TaskTask<T>是必需的,但async不是必需的。这在@ReedCopsey的答案和以下示例中(从this useful SO answer略作改编)中可以看出:

public Task<int> MethodTaskAsync(int arg0, int arg1)
{
    Task<int> task = new Task<int>(() => Method(arg0, arg1));
    task.Start(); // Hot task (started task) should always be returned.
    return task;
}

这就是为什么接口方法签名不需要且不能拥有async关键字的原因:“异步”方法本身就是 just < / em>一种返回开始(并且可能已经完成)的TaskTask<T>的方法。

如果async没有将方法标记为异步方法,它会做什么?这是一种更简单地编写异步方法的方法:将异步方法应用于方法后,可以使用await关键字来告诉编译器非常简单地正确地为您处理辅助异步调用(没有它,您可以尝试使用上面的代码块中的更多代码来手动处理辅助Task,但是这样做会非常复杂且容易出错。

因此,如果您只想从“异步”(即Task-返回)方法中返回已完成的不做事的任务,则可以并且应该同步(!),如@ ReedCopsey使用Task.CompletedTaskTask.FromResult(...)的答案。