Thread-sichere Entity Framework 6
Nur Start-Prüfung EF6 und seine Async-Funktionen.
Junge war ich überrascht, als ich erkannte, dass Sie nicht thread-safe. Ich irgendwie davon ausgegangen, dass war der Punkt.
Hatte ich mein eigenes Task
basierte Erweiterung Methoden seit Jahren schon, aber was ich darauf wartete, sich von EF zu machen, war Sie thread-sicher.
Zumindest mein Task-basierte Funktionen lock
ed, um nicht gegenseitig stören. EF6 gar nicht so weit gehen. Aber das größte problem ist etwas, dass meine code-shares mit den ihrigen. also Versuchen Erteilung einer asynchronen Abfrage und dann vor Abschluss versuchen Sie, auf eine navigationseigenschaft (auf einer pre-loaded völlig separate Einheit, die im gleichen Kontext) auslöst, lazy loading. Diese könnte ausgelöst werden, entweder durch die Benutzeroberfläche oder durch anderen code außerhalb des unmittelbaren Funktion, oder ein Dutzend andere Szenarien.
Soweit ich das sagen kann. Die nur zwei gemeinsame (zwischen Entitäten) veränderliche Ressourcen in einem dbContext sind die Verbindung und die änderungsnachverfolgung (caching). Wenn wir könnten hinzufügen sperren um diese Funktionalitäten dann hätten wir eine thread-sichere Kontext.
Könnten wir auch tun, es in zwei Stufen. Wenn wir umsetzen konnte einen Anbieter, der gesperrt die eine zentrale Funktion verwendet, um die Datenbank abzufragen. Dann ist jede nicht verfolgt Abfragen - entweder durch Rücksendung nicht-Entität (anonymen) Objekten oder durch aufrufen AsNoTracking() - thread wäre sicherer, und sicher sein würde, zu rufen, mit Async-Funktionen, auch wenn ein anderer thread vielleicht Fragen, für ein lazy geladene Objekt.
Unserer Skalierbarkeit wäre nicht schlechter dran, dann sind wir jetzt dass wir mit einem Kontext pro thread, und auch das Async-Funktionen sind aus der Tabelle, wenn Sie versuchen, Sie zu überspringen, auch ein warten auf die Einführung einer bit-Parallelität oder arbeiten in einem evented system (wie in wpf), die auslösen könnte, sobald die erwartete Funktion gibt, mit der Aufgabe.
Also meine Frage ist. Hat jemand implementiert einen Anbieter wie diesen. Oder wäre jemand bereit, mit mir zu arbeiten auf?
- Seine interessant, dass EF6 nicht nur ist thread-unsafe, aber Gewinde ist. Der Punkt, der EF6 und
Async
Funktionen ist NICHT einfädeln. In der Tatasync
await
ist kein threading framework. Eineasync
Rahmen. Sie können schreiben, single threaded asynchrone Anwendungen, in der Tat ist die einzige Sache, die Sie tun können, innode.js
. - Ich glaube, der Allgemeine Leitlinien bei der Verwendung von EF6
async
ist das deaktivieren von lazy loading vollständig. Andernfalls müssen Sie eine Mischung aus asynchronen und blocking-code, die immer Verhaltens-Macken. - Sie haben gelesen oder gehört, eine Menge von Microsoft-propaganda, ohne tatsächlich zu verstehen.
async
await
Umgesetzt werden KÖNNEN, mit node.js style single-threaded asynchrone Handhabung. Manchmal, wenn Sie verwendenasync
await
Sie sind tatsächlich nicht multithreading aber eher die nur darauf warten für ein externes system zu nennen, wieder in den code. Aber die meisten der ZeitTask
s tatsächlich umgesetztThread
s.Task
s das sind, wasasync
await
auf gebaut ist, sind eine Abstraktion, die kann in der Tat entweder die Umsetzung, sondern ist in der Regel threading. - Das kann der Allgemeine Hinweise aufgrund der aktuellen Umsetzung. Aber wenn jemand waren, um die Arbeit der Dienstleister, die
lock
ed rund um den Datenbank-Zugriff. Dann wären wir beide zusammen. - Der Punkt ist, dass Sie würde nicht wollen, zu. Lazy loading wird unnötig blockiert ein thread auf eine asynchrone operation. Wenn Sie entweder
Include
die zugehörigen Entitäten oder eine getrennte (asynchrone) follow-up der Wunsch, Ihr code wird vollständig asynchron. - Die meisten der Zeit, die asynchrone
Task
s basieren auf (logische) Ereignisse, nicht threads. Dies ist insbesondere wahr in EF6. - Ich war versuchen zu ziehen, ist die Unterscheidung zwischen asynchroner und paralleler. Ja ich weiß, dass async-await verwendet werden KÖNNEN, zu Lesen. Aber das problem hier ist nicht CPU-gebunden, aber die Latenz gebunden. Threading erhöht die Ineffizienz. Callback-basierte event-handling steigert die Effizienz. Ich bin daher überrascht, dass das EF-team nicht Marschall zurück an den aufrufenden thread, jedes mal.
- Threading in meine ehrliche Meinung, sollte nur in zwei Situationen eingesetzt werden zu Steigerung der CPU-Ressourcen für (lokal)CPU-bound Prozesse und eine Unterkategorie, dass die segregation der CPU-Zeit für performance-sensitive Prozesse. SQL-Aufrufe nicht CPU-gebunden!
- Ich bin überrascht, wie Sie sind, dass das EF-team verwendet threading zu implementieren asyncrony, und nicht nur logische Ereignisse. @Stephen-Sie haben in der Tat-threads an, die ist, warum der Betrieb der synchronen code bringt das system nach unten, anstatt nur verzögern die Rückkehr. Am Ende des Tages immer mit
Include
oder imperativem code ist nicht immer eine option und zwingt Sie zu verzichten, einige der wichtigsten features von EF gibt. Während alle, die in der Lage wäre zu realisieren, wenn wir nur mit einer einzigen Funktion in einemlock
- Es gibt einige überschneidungen mit der Diskussion hier: stackoverflow.com/questions/20993007/... , wo die Idee, dass "Sie sind nicht thread-sicher". Die Diskussion dort scheint zu suggerieren, dass Sie sind, in welchem Fall diese Frage ist nicht mehr wirklich gültig.
- Ich denke, Sie sollten mit mehr dbcontexts.
- Das einzige Problem, das ich habe ist, dass ich gelegentlich erhalten Sie ein thread-switch nach SaveChangesAsync() und ich war die Speicherung einige Elemente auf einer threadstatic-Sammlung um einige der Protokollierung. Die Einheiten würden dann scheinen zu fehlen; ich habe mich um Sie, indem Sie eine lokale Kopie vor dem Aufruf SaveChangesAsync; so lange, wie alle Verwandte Unternehmen waren begierig darauf geladen (oder ich nur zugegriffen value types), funktionierte es gut.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube, Sie stehen vor einem architektonischen Problem. Was Sie beschreibt, ist eine Anwendung, wo die UI direkt verwendet EF-Objekte, und es bricht die "separation of concerns" - Paradigma.
Auf meiner Seite, ich benutze den Zoll-thread-safe-caches auf ein Modell-Ebene, sodass alles, was passiert auf der Modell-Ebene. Ich implementierte thread-Sicherheit auf meinen cache mit dem bekannten AsyncLock.
DbContext-Objekte, und jedes EF-CRUD-bezogene Operationen haben eine sehr begrenzte Lebensdauer. Jeder CRUD-Operation instanziieren eigene DbContext, und gibt Modell-Objekte in den cache, dann die Zusammenhänge sind Müll gesammelt. Meine Anwendungen verwendet caches als Abstraktions-layer, und caches verwendet EF DB-Abstraktions-Schicht.
Beispielsweise die Erkundung angefügte Eigenschaften, die auf Objekte erfolgt durch die Implementierung von benutzerdefinierten Methoden, die auf der Modell-Ebene, die die Objekt-Id als parameter und liefert eine Liste der verwandten Objekte in den cache. Die Benutzeroberfläche fordert den Cache und die Cache-fragt EF, dann sobald verfügbar, wird der Anruf aus dem cache gibt Objekte auf der Benutzeroberfläche. So einfach ist das.
EntityFramework ist nicht threadsicher entworfen, so gibt es keine Möglichkeit, mit ihm zu arbeiten in einer multi-threaded Weg. (EF thread-Sicherheit)
Anstatt paralleler Zugriff auf Sie DbContext, bauen Sie ein Modell-Ebene zugegriffen werden kann, in einer multi-threaded Weg. Und Ihr Modell kann mehrere parallele nennt Ihnen die DB, aber Bedenken Sie, dass jeder Aufruf instanziiert werden müssen und halten Sie es auf eigene DbContext. Am Ende jedes Anrufs, die im Zusammenhang DbContext entsorgt werden müssen.
DbContext sind wirklich schnell zu instanziieren, der einzige Nachteil ist die Netzwerk-Latenz. Deshalb ist ein cache-Speicher ist eine gute Idee.