c# concurrency entity-framework-4 thread-safety datacontext

c# - Entity Framework Thread Safety



concurrency entity-framework-4 (3)

Los objetos de contexto generados por Entity Framework no son seguros para subprocesos.

¿Qué SaveChanges() si utilizo dos contextos de entidad separados, uno para cada subproceso (y llamo a SaveChanges() en cada uno)? ¿Será seguro para subprocesos?

// this method is called from several threads concurrently public void IncrementProperty() { var context = new MyEntities(); context.SomeObject.SomeIntProperty++; context.SaveChanges(); }

Creo que el contexto del marco de la entidad implementa algún tipo de variable ''contador'' que realiza un seguimiento de si los valores actuales en el contexto son nuevos o no.

  1. Con el código anterior, llamado desde subprocesos separados, ¿aún necesito bloquear el incremento / cambio de espacio?
  2. Si es así, ¿cuál es la forma preferida de lograr esto en este simple escenario?

Creo que "SomeObject.SomeIntProperty" es estático. Esto no tiene nada que ver con que la entidad sea segura para hilos. Si está escribiendo en una variable estática en un entorno multiproceso, siempre debe envolverlas con un doble control de bloqueo para garantizar la seguridad de la hebra.


Más de un subproceso que opera en un único contexto de Entity Framework no es seguro para subprocesos.

Una instancia separada de contexto para cada subproceso es segura para subprocesos. Mientras cada subproceso de ejecución tenga su propia instancia de contexto EF, estará bien.

En su ejemplo, puede llamar a ese código desde cualquier cantidad de subprocesos simultáneamente y cada uno estará felizmente trabajando con su propio contexto.

Sin embargo, sugeriría implementar un bloque de ''uso'' para esto de la siguiente manera:

// this method is called from several threads concurrently public void IncrementProperty() { using (var context = new MyEntities()) { context.SomeObject.SomeIntProperty++; context.SaveChanges(); } }


Puede utilizar el enfoque de fábrica para inyectar su DbContext como una fábrica en lugar de un perse de instancia, eche un vistazo a esto: https://github.com/vany0114/EF.DbContextFactory

Es más seguro y evita codificar la creación de la instancia en sus repositorios.

http://elvanydev.com/EF-DbContextFactory/

Hay una extensión para Ninject para hacerlo de una manera muy sencilla, simplemente llamando al método kernel.AddDbContextFactory<YourContext>(); También necesita cambiar su repositorio al recibir un Func<YourContext>