此示例使用 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/