在方法返回之前,只有下面方法的最后一行使用' await',这并不意味着该方法基本上是同步的,应该只调用"得到()"没有async修饰符和后缀Async?
public virtual async Task<TEntity> GetAsync(Guid id)
{
// some more code here
return await _dbSet.FindAsync(id);
}
答案 0 :(得分:15)
这不意味着该方法基本上是同步的
没有。这是异步的。您可能正在考虑顺序(从一件事情进展到下一件事情),而不是同步(阻止当前线程)。 await
将暂停方法(按顺序)但不阻塞线程(异步)。有关详细信息,请参阅我的async
intro。
没有async修饰符
虽然可以忽略async
/ await
个关键字,但我建议您不要这样做。这是因为// some more code here
可能会抛出异常。我在eliding async
and await
的博客文章中介绍了这一点和其他注意事项。
和后缀Async?
不,该后缀适用于任何返回等待的方法(例如Task
)。因此,即使您忽略了async
和await
,它仍然会返回应该等待的任务,因此它仍然应该具有Async
后缀。< / p>
您可以这样考虑:Async
后缀是API接口的一部分。 async
关键字是一个实现细节。他们经常在一起,但并非总是如此。
答案 1 :(得分:2)
这是一个意见问题。通常,命名约定是返回Task
或Task<T>
后缀为Async
的任何内容。
上面的例子虽然会更好地编写,所以你没有额外的异步包装开销。这是因为您不需要等待该方法中的结果。如果直接使用该方法,该方法的使用者将等待结果。
public virtual Task<TEntity> GetAsync(Guid id, params Expression<Func<TEntity, object>>[] includeProperties))
{
// some more code here
return _dbSet.FindAsync(id);
}
答案 2 :(得分:0)
await
不会阻止。 异步等待以完成操作。这意味着原始线程在等待时被释放。在桌面应用程序中,这意味着在等待例如HTTP或数据库调用完成时释放UI线程。
当该操作完成时,执行将返回到原始线程(对于桌面应用程序)。
实际上,您可以删除async
和await
关键字并立即返回任务来简化代码。代码对操作的结果没有任何作用,因此不需要等待它完成。这将由方法的调用者完成:
public virtual Task<TEntity> GetAsync(Guid id)
{
// some more code here
return _dbSet.FindAsync(id);
}
此代码中的实际异步操作是FindAsync
。 async
关键字只是语法糖,可让您使用await
关键字。如果您不需要await
,则不需要async
关键字
答案 3 :(得分:-1)
在许多情况下,使用Async的每个异步方法的后缀都是多余的。如果您的方法返回Task
或Task<T>
,其目的是从数据库或其他网络资源获取数据,那么它当然是异步运行的。如果您忘记等待某事,编译器也几乎总会给您一个错误。考虑到这一点,使用Async
后缀异步方法有一些很好的理由:
Task
使用Async
后缀方法名称意味着指示该方法以异步方式运行,此方法可以执行此操作。是使用async/await
还是直接返回另一个Task是实现细节。想象一下,你正在审查一些调用忘记使用await的方法的代码。以下哪一项使错误更明显?
var item1 = _example.Get(itemId1);
var item2 = _example.GetAsync(itemId2);
基于其他任何事情,没有理由相信第一行有任何问题。第二行至少会引起一些人的注意。