loops - 循环中的异步和等待多个任务,如何返回单个任务

标签 loops task-parallel-library async-await c#-5.0 entity-framework-6

此示例使用 Entity Framework ,但问题更多是关于如何在循环内等待多个异步任务。假设我在自定义 DbContext 类上有以下方法:

public async Task DiscardChangesAsync()
{
    foreach (var entry in ChangeTracker.Entries().Where(x => x != null))
    {
        switch (entry.State)
        {
            case EntityState.Added:
                entry.State = EntityState.Detached;
                break;
            case EntityState.Modified:
                entry.State = EntityState.Unchanged;
                break;
            case EntityState.Deleted:
                await entry.ReloadAsync(); // <-- only async method
                break;
        }
    }
}

上面的代码可以编译并运行,但我不确定它的效率如何。例如,如果上下文包含 10 个已删除的实体条目,则线程会在每个 ReloadAsync 处停止并等待,然后再继续循环,对吧?有没有办法让循环继续执行,并返回一个新的 Task,该任务在所有 10 个 ReloadAsync 调用完成之前不会完成?

最佳答案

严格回答您的问题:

public Task DiscardChangesAsync()
{
    List<Task> tasks = new List<Task>();
    foreach (var entry in ChangeTracker.Entries().Where(x => x != null))
    {
        switch (entry.State)
        {
            case EntityState.Added:
                entry.State = EntityState.Detached;
                break;
            case EntityState.Modified:
                entry.State = EntityState.Unchanged;
                break;
            case EntityState.Deleted:
                tasks.Add(entry.ReloadAsync());
                break;
        }
    }

    return Task.WhenAll(tasks);
}

不过,让 EF 一次性重新加载所有这些可能会更有效:

public Task DiscardChangesAsync()
{
    List<DbEntityEntry> deleted = new List<DbEntityEntry>();

    foreach (var entry in ChangeTracker.Entries().Where(x => x != null))
    {
        switch (entry.State)
        {
            case EntityState.Added:
                entry.State = EntityState.Detached;
                break;
            case EntityState.Modified:
                entry.State = EntityState.Unchanged;
                break;
            case EntityState.Deleted:
                deleted.Add(entry);
                break;
        }
    }

    return ctx.RefreshAsync(RefreshMode.StoreWins, deleted);
}

关于loops - 循环中的异步和等待多个任务,如何返回单个任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20527272/

相关文章:

java - 为什么 while 循环后没有打印任何内容?

python-3.x - 陷入python中的循环 - 只返回第一个值

javascript - 为什么 JavaScript 函数需要关键字 "async"? "await"关键字还不够吗?

javascript - 在没有变量声明的情况下使用异步迭代

matlab - 如何改变Matlab中的循环条件?

swift - 循环和范围运算符的基准

.net - 我怎样才能让一个 IPropagatorBlock<TInput, TOutput> 自动停止?

c# - 关于 Task.Start() 、 Task.Run() 和 Task.Factory.StartNew() 的用法

c# - 默认 SynchronizationContext 与默认 TaskScheduler

javascript - 如何在 Unity/C# WebGL 平台中调用 async/await JavaScript 函数?