Domanda

Sto appena iniziando a testare EF6 e le sue funzioni Async. Il ragazzo mi ha sorpreso quando ho capito che non sono thread safe. Ho pensato che fosse questo il punto.

Avevo già i miei metodi di estensione basati su Task da anni, ma quello che stavo aspettando da EF era renderli sicuri.

Almeno le mie funzioni basate su Task si lock per non interferire l'una con l'altra. EF6 non arriva nemmeno così lontano. Ma il problema principale è qualcosa che il mio codice condivide con il loro. Ad esempio, prova a rilasciare una query asincrona e, prima di completarla, prova ad accedere a una proprietà di navigazione (su un'entità completamente separata precaricata nello stesso contesto) che attiva il caricamento lento. Questo potrebbe essere attivato dall'interfaccia utente o da un altro codice al di fuori della funzione immediata o da una dozzina di altri scenari.

Per quanto posso dire. Le uniche due risorse mutabili condivise (tra entità) in un dbContext sono la connessione e il rilevamento delle modifiche (memorizzazione nella cache). Se potessimo aggiungere il blocco di quelli alle funzionalità, avremmo un contesto thread-safe.

Potremmo persino farlo in due fasi. Se potessimo implementare un provider che ha bloccato la funzione centralizzata utilizzata per interrogare il database. Quindi qualsiasi query non tracciata - restituendo oggetti non anonimi (anonimi) o chiamando AsNoTracking () - sarebbe thread-safe, e sarebbe sicuro chiamare con funzioni asincrone anche quando un altro thread potrebbe richiedere un oggetto lazy loaded.

La nostra scalabilità non peggiorerebbe, quindi ora dobbiamo usare un contesto per thread e anche le funzioni Async sono fuori dal tavolo se si tenta di saltare anche solo una attesa per introdurre un po 'di parallelismo o lavorare in un evento sistema (come wpf) che potrebbe innescarsi una volta che la funzione attesa ritorna con l'attività.

Quindi la mia domanda è. Qualcuno ha implementato un provider come questo. O qualcuno sarebbe disposto a collaborare con me?

Risposta popolare

Penso che tu stia affrontando un problema architettonico. Quello che descrivi è un'applicazione in cui l'interfaccia utente utilizza direttamente oggetti EF e interrompe il paradigma della "separazione delle preoccupazioni".

Da parte mia, utilizzo le cache doganali thread-safe su un livello Model, lasciando che tutto avvenga nel livello Model. Ho implementato la sicurezza del thread sulla mia cache con il noto AsyncLock.

Oggetti DbContext e ogni operazione relativa a EF CRUD ha una durata molto limitata. Ogni operazione CRUD istanzia il proprio DbContext e restituisce oggetti modello alla cache, quindi i contesti vengono eliminati. Le mie applicazioni utilizzano le cache come livello di astrazione e le cache utilizzano EF come livello di astrazione DB.

Ad esempio, l'esplorazione delle proprietà associate sugli oggetti viene eseguita implementando metodi personalizzati sul livello Model, che accetta l'oggetto ID come parametro e restituisce un elenco di oggetti correlati alla cache. L'interfaccia utente chiede la cache, quindi la cache chiede EF, quindi, una volta disponibile, la chiamata effettuata alla cache restituisce oggetti all'interfaccia utente. Semplice come quella.

EntityFramework non è progettato per essere thread-safe, quindi non c'è modo di lavorarci in modo multi-thread. ( Sicurezza del filo EF )

Invece di disporre dell'accesso parallelo a DbContext, devi creare un livello Model a cui è possibile accedere in modalità multi-thread. E il tuo modello può effettuare più chiamate parallele al tuo DB, ma tieni presente che ogni chiamata deve creare un'istanza e mantenere il proprio DbContext. Alla fine di ogni chiamata, il relativo DbContext deve essere eliminato.

DbContext è davvero veloce da istanziare, l'unico lato negativo è la latenza della rete. Ecco perché una memoria cache è una buona idea.




Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché