Entity Framework and Multi threading

Martin Richards picture Martin Richards · Feb 1, 2012 · Viewed 63.6k times · Source

We are having some trouble designing our multi-threaded Entity Framework driven application and would like some guidance. We are creating entities on different threads, the entities are added to collections which are then data-bound to various WPF controls. The ObjectContext class is not thread-safe, so managing this we have essentially have 2 solutions:

Solution 1 has a single context and carefully use locking to ensure no 2 threads access it at the same time. This would be relatively simple to implement but would require the context to be alive for the duration of the application. Is it a bad idea to have a single context instance open like this?

Solution 2 is to create context objects on-demand and then detach the objects immediately, then hold them in our own collections, then re-attach them to do any updating. This has some serious problems for use though, as when the objects are detached they lose references to the navigation property objects. Also there is the problem that 2 threads could still try to access a single object, and both try to attach() it to a context. Also, we would need to supply a new context every time we wanted to access entities' navigation properties.

Q: Are either of the two solutions valid, if not how do you recommend we tackle this?

Answer

Chris Shain picture Chris Shain · Feb 1, 2012

First off, I'm assuming you have read the article "Multithreading and the Entity Framework" on MSDN.

Solution #1 is almost certainly the safest from a threading perspective, since you are guaranteeing that only one thread is interacting with the context at any give time. There is nothing inherently wrong with keeping the context around- it isn't keeping database connections open behind the scenes, so it's just memory overhead. This could, of course, present a performance problem if you end up bottlenecked on that thread and the whole application is written with single-db-thread assumptions.

Solution #2 seems unworkable to me- you'd end up with subtle bugs throughout the application where people forget to re-attach (or detach) entities.

One solution is to not use your entity objects in the UI layer of the application. I'd recommend this anyway- chances are, the structure/layout of the entity objects is not optimal for how you want to display things on your user interface (this is the reason for the family of MVC patterns). Your DAL should have methods which are business logic specific (UpdateCustomer for instance), and it should decide internally whether to create a new Context or use a stored one. You can start with the single stored context approach, and then if you run into bottleneck issues you have a limited surface area where you need to make changes.

The downside is that you need to write a lot more code- you'd have your EF entities, but you'd also have business entities that have duplicate properties and potentially differing cardinality of many of the EF entities. To mitigate this, you can use frameworks like AutoMapper to simplify copying properties from the EF entities to the business entities and back again.