我想从db重新加载某些实体,因为我希望使用async / await重新加载它们。这是我的代码:
private async void btnUpdate_Click(object sender, EventArgs e)
{
Task allTasks = UpdateAppointments();
await allTasks;
}
internal async Task UpdateAppointments()
{
IEnumerable<Entities.Apointment> apps = PContext.Appointments.Select(p => p).Where(p => p.Start >= Start && p.End <= End && p.MachineId == 66);
List<Task> task = new List<Task>();
foreach (Entities.Apointment app in apps)
{
task.Add(PContext.Entry(app).ReloadAsync());
}
await Task.WhenAll(task);
}
我收到错误:
在上一次异步操作完成之前,在此上下文中启动了第二个操作。使用&#39;等待&#39;确保任何 在调用另一个方法之前已完成异步操作 在这种背景下。任何实例成员都不能保证是线程 安全的。**
异常详情:
{System.NotSupportedException:在上一个异步操作完成之前,在此上下文中启动了第二个操作。使用&#39;等待&#39;确保在调用此上下文中的另一个方法之前已完成任何异步操作。任何实例成员都不保证是线程安全的。 在System.Data.Entity.Internal.ThrowingMonitor.EnsureNotEntered() at System.Data.Entity.Core.Objects.ObjectContext.RefreshAsync(RefreshMode refreshMode,Object entity,CancellationToken cancellationToken) 在System.Data.Entity.Internal.InternalEntityEntry.ReloadAsync(CancellationToken cancellationToken) 在System.Data.Entity.Infrastructure.DbEntityEntry`1.ReloadAsync() 在C:\ Git \ planningmodule \ PlanningModule \ PlanningForm.cs中的PlanningModule.PlanningForm.d__20.MoveNext():第307行 ---从抛出异常的先前位置开始的堆栈跟踪结束--- 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.GetResult() 在C:\ Git \ planningmodule \ PlanningModule \ PlanningForm.cs中的PlanningModule.PlanningForm.d__19.MoveNext():第264行}
内部异常:
空
堆栈追踪:
_stackTrace {sbyte [192]} object {sbyte []}
Anys的想法,如何重新加载实体异步?
答案 0 :(得分:2)
您需要具体化列表,然后才能对DbContext
执行其他操作,因为在您枚举DbContext
时正在使用IQueryable
。因此,添加.ToList()
可以解决问题,因为在迭代开始之前,所有实体都会从DbContext
中检索出来。
foreach (Entities.Apointment app in apps.ToList()) // added ToList()
如果您想使用async
来实现列表,则可以
foreach (Entities.Apointment app in (await apps.ToListAsync()))
编辑 来自评论
我应该注意到,我得到的错误通常与重新加载的许多实体有关(&gt; 1000)
我能想到的唯一另一件事是await Task.WhenAll(task);
中存在竞争条件,其中任务(您在此声明之前的循环中定义)同时调用{ {1}}。没有其他信息,我无法确切地告诉你(让我知道它是完全相同的错误还是不同的错误)。在这种情况下,您应该在循环内同步执行每个调用,这仍然可以使用await / async调用来完成。
DbContext