Innerhalb einer ASP.NET MVC-Anwendung erhalte ich die folgende Fehlermeldung für eine meiner Controller-Methoden, die meine Entity Framework-Kontext verwendet.Warum wird keine zweite Operation im EF Kontext zu verhindern scheint
Eine zweite Operation wurde in diesem Kontext gestartet, bevor eine vorherige asynchrone Operation abgeschlossen wurde. Verwenden Sie 'abwarten', um sicherzustellen, dass alle asynchronen Vorgänge abgeschlossen sind, bevor Sie eine andere Methode in diesem Kontext aufrufen. Es ist nicht garantiert, dass alle Instanzmitglieder Thread-sicher sind.
Ich bin mir bewusst, dass Sie keine Abfragen parallel ausführen können, und alles scheint richtig erwartet zu werden. Wenn ich das Programm debuggen und einige der von EF zurückgegebenen Daten schrittweise überprüfe und überprüfe, funktioniert es wahrscheinlich, weil dies die Abfragen zum Abschluss bringt.
BEARBEITEN Wenn ich einen Haltepunkt bei der Nullprüfung in der Controller-Methode platzieren und die Daten von shipmentDetail
untersuchen, wird die Ausnahme NICHT ausgelöst.
Hier ist ein snippit des Codes:
Controller-Methode:
[Route("{id:int}/Deliveries")]
public async Task<ActionResult> 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);
}
Create Methode:
public static async Task<DeliveryInfoModel> CreateModel(Context db, ShipmentDetail shipment)
{
DeliveryInfoModel model = new DeliveryInfoModel()
{
ShipmentInfo = shipment
};
//initialize processing dictionary
Dictionary<int, bool> boxesProcessed = new Dictionary<int, bool>();
List<DeliveryBoxStatus> statuses = new List<DeliveryBoxStatus>();
for (int i = 1; i <= shipment.BoxCount; i++)
{
boxesProcessed.Add(i, false);
}
//work backwards through process
//check for dispositions from this shipment
if(shipment.Dispositions.Count > 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;
}
ich nicht ganz sicher bin, ob es wegen der ist Abfrage im Controller gemacht, oder wegen der Abfragen in der Schleife, die nicht c sind ompleting verursacht dieses Verhalten. Gibt es etwas, das ich nicht verstehe, wenn die Anfragen aufgrund der Faulheit von EF tatsächlich gemacht/zurückgegeben werden oder wie async/wait in dieser Situation funktioniert? Ich habe eine Menge anderer Methoden & Controller, die async EF-Aufrufe machen und haben nicht zuvor in diesem ausgeführt. mit Ninject als mein IoC-Container
EDIT
ist mein Kontext in meinen Controller injiziert. Hier ist seine Konfiguration innerhalb von NinjectWebCommon der RegisterServices Methode:
kernel.Bind<Context>().ToSelf().InRequestScope();
ich vermuten, dass Ihr Fehler von woanders kommt, sollte dieser Code in Ordnung sein. A) Ist Ihre 'db' mit anderen Ansichten/View-Modellen geteilt? B) Bist du mit einem Debugger durchgegangen, um zu sehen, ob es noch würfelt? – CodingGorilla
A) Nein, es wird nicht geteilt, es wird in den Controller injiziert und nur dort verwendet, dies sind die einzigen 2 Operationen, die den 'db'-Kontext für diese HTTP-Anfrage verwenden. B) Die Verwendung eines Debuggers löst nicht aus, wenn ich die von EF zurückgegebenen Daten überprüfe (ich erwähnte dies in der Frage), andernfalls tut es das. – JNYRanger
Können Sie erweitern, wie es injiziert wird? Wird es aus einem IoC-Container injiziert? Wenn ja, wie ist Ihre IoC-Registrierung konfiguriert? – CodingGorilla