为什么等待不会出现阻止EF上下文的第二次操作

在ASP.NET MVC应用程序中,我收到了一个使用我的Entity Framework上下文的控制器方法的以下错误消息。

在先前的异步操作完成之前,在该上下文上开始第二个操作。 使用’await’确保在此上下文上调用另一个方法之前已完成任何异步操作。 任何实例成员都不保证是线程安全的。

我知道你不能并行运行查询,所有东西似乎都在等待。 如果我调试程序并逐步检查从EF返回的一些数据,那么它可以工作,可能是因为这会强制查询完成。

编辑如果我在控制器方法的空检查中放置一个断点并检查shipmentDetail的数据,则不会抛出exception。

这是代码的一部分:

控制器方法

 [Route("{id:int}/Deliveries")] public async Task DeliveryInfo(int id) { var shipmentDetail = await db.ShipmentDetails.SingleOrDefaultAsync(s => s.Id == id); if (shipmentDetail == null) return HttpNotFound(string.Format("No shipment detail found with id {0}", id)); var model = await DeliveryInfoModel.CreateModel(db, shipmentDetail); return View("DeliveryInfo", model); } 

CreateModel方法

 public static async Task CreateModel(Context db, ShipmentDetail shipment) { DeliveryInfoModel model = new DeliveryInfoModel() { ShipmentInfo = shipment }; //initialize processing dictionary Dictionary boxesProcessed = new Dictionary(); List statuses = new List(); for (int i = 1; i  0) { foreach (var d in shipment.Dispositions) { DeliveryBoxStatus status = new DeliveryBoxStatus() { BoxNumber = d.BoxNumber, LastUpdated = d.Date, Status = d.Type.GetDescription().ToUpper() }; statuses.Add(status); boxesProcessed[d.BoxNumber] = true; } } //return if all boxes have been accounted for if (boxesProcessed.Count(kv => kv.Value) == shipment.BoxCount) { model.BoxStatuses = statuses; return model; } //check for deliveries if(shipment.Job_Detail.Count > 0) { foreach (var j in shipment.Job_Detail.SelectMany(d => d.DeliveryInfos)) { DeliveryBoxStatus status = new DeliveryBoxStatus() { BoxNumber = j.BoxNumber, LastUpdated = j.Job_Detail.To_Client.GetValueOrDefault(), Status = "DELIVERED" }; statuses.Add(status); boxesProcessed[j.BoxNumber] = true; } } //check for items still in processing & where foreach (int boxNum in boxesProcessed.Where(kv => !kv.Value).Select(kv => kv.Key)) { //THIS LINE THROWS THE EXCEPTION var processInfo = await db.Processes.Where(p => p.Jobs__.Equals(shipment.Job.Job__, StringComparison.InvariantCultureIgnoreCase) && p.Shipment == shipment.ShipmentNum && p.Box == boxNum) .OrderByDescending(p => p.date) .FirstOrDefaultAsync(); //process returned data //... } model.BoxStatuses = statuses; return model; } 

我不完全确定这是因为在控制器中进行的查询,还是因为在循环中进行的查询未完成导致此行为。 由于EF的懒惰,或者async / await如何在这种情况下工作,是否有什么我不了解实际查询/返回的时间? 我有很多其他方法和控制器可以进行异步EF调用,并且之前没有遇到过这种情况。

编辑

我的上下文使用Ninject作为我的IoC容器注入我的控制器。 这是NinjectWebCommon的RegisterServices方法中的配置:

 kernel.Bind().ToSelf().InRequestScope(); 

与Entity Framework使用异步时避免延迟加载。 相反,要么首先加载您需要的数据,要么使用Include()来确保您需要的数据随查询一起加载。

https://msdn.microsoft.com/en-gb/magazine/dn802603.aspx

异步支持的当前状态

…异步支持在版本6中添加到Entity Framework(在EntityFramework NuGet包中)。 但是,在异步工作时必须小心避免延迟加载,因为延迟加载总是同步执行 。 …

(强调我的)

也:

https://entityframework.codeplex.com/wikipage?title=Task-based%20Asynchronous%20Pattern%20support%20in%20EF.#ThreadSafety