当一个方法仅在return语句中等待时,标记一个异步是否有用?

时间:2017-01-25 15:32:46

标签: c# async-await

在方法返回之前,只有下面方法的最后一行使用' await',这并不意味着该方法基本上是同步的,应该只调用"得到()"没有async修饰符和后缀Async?

public virtual async Task<TEntity> GetAsync(Guid id)
{
    // some more code here
    return await _dbSet.FindAsync(id);
}

4 个答案:

答案 0 :(得分:15)

  

这不意味着该方法基本上是同步的

没有。这是异步的。您可能正在考虑顺序(从一件事情进展到下一件事情),而不是同步(阻止当前线程)。 await将暂停方法(按顺序)但不阻塞线程(异步)。有关详细信息,请参阅我的async intro

  

没有async修饰符

虽然可以忽略async / await个关键字,但我建议您不要这样做。这是因为// some more code here可能会抛出异常。我在eliding async and await的博客文章中介绍了这一点和其他注意事项。

  

和后缀Async?

不,该后缀适用于任何返回等待的方法(例如Task)。因此,即使您忽略了asyncawait,它仍然会返回应该等待的任务,因此它仍然应该具有Async后缀。< / p>

您可以这样考虑:Async后缀是API接口的一部分。 async关键字是一个实现细节。他们经常在一起,但并非总是如此。

答案 1 :(得分:2)

这是一个意见问题。通常,命名约定是返回TaskTask<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线程。

当该操作完成时,执行将返回到原始线程(对于桌面应用程序)。

实际上,您可以删除asyncawait关键字并立即返回任务来简化代码。代码对操作的结果没有任何作用,因此不需要等待它完成。这将由方法的调用者完成:

public virtual Task<TEntity> GetAsync(Guid id)
{
    // some more code here
    return _dbSet.FindAsync(id);
}

此代码中的实际异步操作是FindAsyncasync关键字只是语法糖,可让您使用await关键字。如果您不需要await,则不需要async关键字

答案 3 :(得分:-1)

在许多情况下,使用Async的每个异步方法的后缀都是多余的。如果您的方法返回TaskTask<T>,其目的是从数据库或其他网络资源获取数据,那么它当然是异步运行的。如果您忘记等待某事,编译器也几乎总会给您一个错误。考虑到这一点,使用Async后缀异步方法有一些很好的理由:

  • 该方法以异步方式运行,但不返回Task
  • 同步运行的另一种同名方法
  • 忘记调用代码中的await不太可能被编译器捕获

使用Async后缀方法名称意味着指示该方法以异步方式运行,此方法可以执行此操作。是使用async/await还是直接返回另一个Task是实现细节。想象一下,你正在审查一些调用忘记使用await的方法的代码。以下哪一项使错误更明显?

var item1 = _example.Get(itemId1);

var item2 = _example.GetAsync(itemId2);

基于其他任何事情,没有理由相信第一行有任何问题。第二行至少会引起一些人的注意。