如何调用嵌套的异步方法

Vah*_*ari 6 c# asynchronous

我想知道什么是调用嵌套异步方法的最佳方法,如果我想要两个方法都是异步的.
首先:调用者方法必须返回Task

public async Task SaveChangesAsync()
{
    await Context.SaveChangesAsync();
}
public Task UpdateAsync(List<TEntity> entities)
{
    foreach (TEntity entity in entities)
    {
        BeforeUpdate(entity);
        Context.Entry(entity).State = EntityState.Modified;
    }
    return SaveChangesAsync();
}
Run Code Online (Sandbox Code Playgroud)


第二:调用方法必须具有async- awaitas called方法

public async Task SaveChangesAsync()
{
    await Context.SaveChangesAsync();
}
public async Task UpdateAsync(List<TEntity> entities)
{
    foreach (TEntity entity in entities)
    {
        BeforeUpdate(entity);
        Context.Entry(entity).State = EntityState.Modified;
    }
    await SaveChangesAsync();
}
Run Code Online (Sandbox Code Playgroud)

ang*_*son 4

这段代码不应该使用async/await,除非这些方法中有一些您没有展示的部分。

换句话说,这些方法应该这样写:

public Task SaveChangesAsync()
{
    return Context.SaveChangesAsync();
}
public Task UpdateAsync(List<TEntity> entities)
{
    foreach (TEntity entity in entities)
    {
        BeforeUpdate(entity);
        Context.Entry(entity).State = EntityState.Modified;
    }
    return SaveChangesAsync();
}
Run Code Online (Sandbox Code Playgroud)

这基本上就是选项 3,你没有展示,async/await根本没有任何痕迹。

原因是代码的执行方式如下:

  1. UpdateAsync它将在调用线程上执行导致等待的所有部分,这意味着foreach循环将在调用线程上执行
  2. 它将执行对SaveChangesAsync()up 的调用,直到返回,仍然在调用线程上
  3. SaveChangesAsync将调用Context.SaveChangesAsync()直到它返回,仍然在调用线程上

简而言之,这些方法的所有工作都已经在调用线程上完成了,剩下的只是Context.SaveChangesAsync. 如果您async/await完全放弃并简单地返回包装异步性的任务,那么您并没有牺牲任何功能,但您已经消除了编译器通过方法为您生成的所有复杂性async/await

一般规则是这样的:

除非您需要在异步方法返回执行某些操作,否则不要使用async/await

由于您的两个方法在调用异步方法后立即结束,因此您最好只返回所涉及的任务而不是使用async/await.

  • “除非您需要在异步方法返回后执行某些操作,否则不要使用 async/await” 是一个很好的规则。 (2认同)