此示例与实体框架有关,但问题更多的是如何在循环中await
多个async
任务。假设我在自定义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
调用完成后才会完成?
答案 0 :(得分:4)
严格回答你的问题:
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);
}