Question

Just started to try EF6's Async features. When I learned that they are not thread safe, boy was I shocked. I sort of thought that was the point.

I had my.Task based extension methods for many years, but I was hoping that EF would give them thread safety.

My Task-based functions, at least.lock ed so as not to conflict with one another. Even EF6 does not go that far. However, the main issue is something that both my code and theirs share. Try running an async query, and then try accessing a navigation property (on a wholly pre-loaded distinct entity in the same context) to cause lazy loading before it has finished. This could be started by the user interface (UI), other code not related to the current function, or a variety of other things.

As far as I'm aware. The connection and change tracking are the only two shared (amongst entities) mutable resources in a dbContext (caching). We would have a thread safe context if we could add locking around those functionalities.

Even two steps would be possible. If we could set up a provider that restricted access to the one primary function that was used to query the database. Then, any non tracked queries would be thread safe and safe to call with Async functions even when another thread might be requesting a lazy loaded object, either by returning non entity (anonymous) objects or by invoking AsNoTracking().

Even Async functions are off the table if you try to skip even one await to introduce a little parallelism or are working in an evented system (like wpf) that might trigger once the awaited function returns with the task, but our scalability would be no worse off than it is now that we have to use one context per thread.

Thus, I have a query. Has a supplier like this been used before. Or would anybody be open to collaborating with me on it?

1
18
11/4/2013 1:13:19 PM

Popular Answer

I believe you are having architectural problems. What you've described violates the "separation of concerns" principle because it uses EF objects directly in the UI.

On my end, I utilize unique thread-safe caches on a Model layer, allowing everything to occur there. I used the renowned AsyncLock to implement thread safety on my cache.

Every EF CRUD related operation, including DbContext objects, have an extremely short lifespan. Every CRUD operation creates its own DbContext, returns Model Objects to the cache, and then garbage collects the contexts. Caches serve as an abstraction layer for my apps, while EF serves as a DB abstraction layer for caches.

For instance, providing new methods on the Model layer that accept the object Id as an argument and return a list of related items to the cache enables users to explore associated properties on objects. When available, the request made to the cache returns objects to the UI. The UI queries the cache, the cache queries the EF. Just like that.

There is no way to work with EntityFramework in a multi-threaded manner because it is not intended to be thread safe. (Safe EF threading)

Build a Model layer that can be accessible in multiple threads in place of having parallel access to your DbContext. Additionally, your model is allowed to make numerous simultaneous calls to your database, but each request must create and maintain a separate DbContext. The associated DbContext needs to be deleted at the conclusion of each call.

The only drawback of DbContext is the network delay because they initialize so quickly. That's why a memory cache is a good idea.

10
1/28/2015 4:04:51 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow