Reputation: 17
I am using Async and await with multi threading.
If I use Async and await on single thread it works fine but when I use multiple threads, it breaks with an error that I am trying to access dbcontext with multiple threads.
I know I can't do that. But now I want have scheduler which will schedule access of dbcontext to each thread.
How can I code such kind of scheduler/ mutex or whatever that solves this issue.
Upvotes: 0
Views: 5404
Reputation: 1270
You can definitely use EF with async/await
, but you can't perform two operations at once on the same context.
In terms of performance, it's actually faster to create two contexts which looks to be the reason you're using async/await
.
For this example, I'd recommend just creating two separate contexts for each CallToDbOps()
.
Upvotes: 3
Reputation: 9725
This is not so much of an answer as information to help [User]...
Have a read of this blog also have a read of this article about Entity Framework specifications for its async pattern support
DbContext is not thread-safe
You must never access your DbContext-derived instance from multiple threads simultaneously. This might result on multiple queries being sent concurrently over the same database connection. It will also corrupt the first-level cache that DbContext maintains to offer its Identity Map, change tracking and Unit of Work functionalities.
In a multi-threaded application, you must create and use a separate instance of your DbContext-derived class in each thread.
So if DbContext isn't thread-safe, how can it support the async query features introduced with EF6? Simply by preventing more than one async operation being executed at any given time (as documented in the Entity Framework specifications for its async pattern support). If you attempt to execute multiple actions on the same DbContext instance in parallel, for example by kicking off multiple SELECT queries in parallel via the the DbSet.ToListAsync() method, you will get a NotSupportedException with the following message:
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
Entity Framework's async features are there to support an asynchronous programming model, not to enable parallelism.
Taken from EF article:
"Thread Safety
While thread safety would make async more useful it is an orthogonal feature. It is unclear that we could ever implement support for it in the most general case, given that EF interacts with a graph composed of user code to maintain state and there aren't easy ways to ensure that this code is also thread safe.
For the moment, EF will detect if the developer attempts to execute two async operations at one time and throw."
Upvotes: 1