UOW - Eine zweite Operation wurde in diesem Kontext gestartet, bevor eine vorherige asynchrone Operation abgeschlossen wurde

9

Ich versuche folgenden Code, er hat zwei Teile, einer ist die Navigation über Prisma. Wenn die Navigation erlaubt ist, starte ich asynchron eine Tiefenladung, aber jedesmal mit einem neuen Kontext. Im späteren Code würde ich anstehende Navigationen abbrechen wollen, die noch nicht fertig geladen sind, aber der untenstehende Code funktioniert nicht, also ist die Stornierung eine Sache für später; -)

Navigationslogik: keine Probleme hier

%Vor%

tiefe Ladelogik:

%Vor%

Ich bekomme immer wieder Ausnahmen, als hätte ich vergessen zu warten, aber das ist niemals der Fall. Ich benutze auch configurewait (true) richtig, wenn ich eine Fortsetzung auf dem GUI-Thread will. Aber ich bekomme diesen Fehler in der deeploading Logik. Die Einheit der Arbeits- und Repository-Klassen verwendet auch den Async-Warte-Mechanismus, aber auch dort warte ich richtig.

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. Alle Instanzmitglieder sind nicht garantiert threadsicher.

Bearbeiten (Loggercode wurde entfernt, um die Codegröße zu reduzieren)

    
Philip Stuyck 04.02.2015, 20:55
quelle

2 Antworten

12

Das Problem ist dieser Code:

%Vor%

UnitOfWork ist eine Instanzvariable, wenn das Szenario ein zweites Mal mit einer neuen Instanz überschrieben wird. Das bereits ausgeführte Szenario verwendet dann dieses neue UnitOfWork anstelle seines eigenen, weil es überschrieben wird. Nicht so einfach zu erkennen, aber eine einfache Race Condition. Ich fand es, indem ich alle Instanzvariablen durch lokale Variablen ersetzte und dann das Problem dislozierte.

    
Philip Stuyck 05.02.2015, 19:07
quelle
0

Dies ist wahrscheinlich nicht die Antwort, sondern ein allgemeiner Blick auf Ihren Code.

Hauptzweck von async / await ist es, den aktuellen Thread verfügbar zu halten. Dadurch wird der UI-Thread nicht blockiert und die App reagiert nicht.

Sie stellen bereits sicher, dass Ihr tiefes Laden in einem ThreadPool-Thread stattfindet, da Sie es vollständig mit Task.Run () starten. Sie können wahrscheinlich die meisten Ihrer Probleme umgehen, indem Sie die standardmäßigen synchronen Methoden von EntityFramework in Ihrem Lademechanismus verwenden.

Zunächst sieht Ihr Code bei den asynchronen Aufrufen fein aus. Vielleicht wird Ihr tiefes Laden mehrfach ausgelöst?

    
Kai Brummund 05.02.2015 02:36
quelle