我有一个IAnimation
公开方法的接口BeginAsync()
。该方法应该启动动画并在完成后返回。
我想做的是实现一个只在执行时返回的null
动画类。NoAnimation
BeginAsync()
这是正确的实施吗?
public async Task BeginAsync()
{
await Task.Run(() => { });
}
我怀疑有比这更优雅的方法。我还考虑过创建一个空方法。但这给了我一个我也不喜欢的警告。
我有一个IAnimation
公开方法的接口BeginAsync()
。该方法应该启动动画并在完成后返回。
我想做的是实现一个只在执行时返回的null
动画类。NoAnimation
BeginAsync()
这是正确的实施吗?
public async Task BeginAsync()
{
await Task.Run(() => { });
}
我怀疑有比这更优雅的方法。我还考虑过创建一个空方法。但这给了我一个我也不喜欢的警告。
只需用于Task.CompletedTask
返回已完成的任务:
public Task BeginAsync()
{
return Task.CompletedTask;
}
如果您有Task<TResult>
用于Task.FromResult<TResult>
返回已完成任务的结果:
public Task<bool> BeginAsync()
{
return Task.FromResult(true);
}
您当前的实现效率非常低,因为它构建了状态机,并且还使用 ThreadPool 线程来运行空任务。
很容易陷入思维的陷阱,async
任何异步方法的签名都必须是其中的一部分。看起来一定是;它(具有误导性!)读起来好像它的全部目的是将方法标记为异步。
但它不是,Task
或者Task<T>
是必需的,但不是async
. 这显示在@ReedCopsey 的答案和以下示例中(稍微改编自这个有用的 SO 答案):
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
关键字:一个“异步”方法本身,不管它是如何实现的,它只是一个返回启动的方法(并且可能已经完成)Task
或Task<T>
。
如果async
不将方法标记为异步,它会做什么?这是一种更简单的写异步方法的方法:一旦你把它应用到一个方法上,你可以使用await
关键字告诉编译器为你正确处理辅助异步调用(没有它,你可以尝试Task
手动处理辅助异步调用) ,在上面的代码块中使用更多类似的代码,但这样做会非常复杂且容易出错)。
因此,如果您只想从“异步”(即Task
-returning)方法返回一个无所事事的、已经完成的任务,您可以并且应该同步(!)这样做,就像在@ReedCopsey 的答案中一样,使用Task.CompletedTask
or Task.FromResult(...)
。