Entity Framework: How to prevent dbcontext getting accessed by multiple threads? - c#

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.

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().

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."

Related

How to run a method that uses an injected DBContext with Asynchronous Tasks to speed up CRM import?

I want to run a method that uses an injected DBContext to make db calls but I want to use several tasks running asynchronously to call said method to make the program run faster. I tried using Parallel.ForEach but got a "A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext" error, realizing that dbcontext isn't thread-safe.
Is there a way to create tasks in a for loop, call the method in question that uses the injected DBContext, but is thread safe? I'm trying to import data into a CRM, and this would significantly speed up the process. I could use a batch insert, but there's a lot of entity associations that would make that very difficult.
I realize there's no code I provided, I'm just wondering if there's a way to even go about doing this, wherein async tasks are created and can hit the DBContext without multiple threads crisscrossing.

EF6 Connected Scenario error : A second operation started on this context before a previous asynchronous operation completed

I am doing a Desktop Application in WPF and as it is said in Entity Framework Tutorial, it is a good idea to use the connected scenario.
So in my application, I have a class that has a static property Dal that contain the dbContext and all database access functions.
It was working well until I started to think about adding some async in the Dal, now I sometimes have this error even if it doesn't change the behavior in my application (just going faster as expected):
System.NotSupportedException: 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.
I checked on every async call functions, everytime I call one, I use await.
I am also using db.SaveChangesAsync() in my Dal's functions.
Maybe I am wrong using a static property for my Dal ?

When should I use Async Controllers in ASP.NET MVC?

I have some concerns using async actions in ASP.NET MVC. When does it improve performance of my apps, and when does it not?
Is it good to use async action everywhere in ASP.NET MVC?
Regarding awaitable methods: shall I use async/await keywords when I want to query a database (via EF/NHibernate/other ORM)?
How many times can I use await keywords to query the database asynchronously in one single action method?
You may find my MSDN article on the subject helpful; I took a lot of space in that article describing when you should use async on ASP.NET, not just how to use async on ASP.NET.
I have some concerns using async actions in ASP.NET MVC. When it improves performance of my apps, and when - not.
First, understand that async/await is all about freeing up threads. On GUI applications, it's mainly about freeing up the GUI thread so the user experience is better. On server applications (including ASP.NET MVC), it's mainly about freeing up the request thread so the server can scale.
In particular, it won't:
Make your individual requests complete faster. In fact, they will complete (just a teensy bit) slower.
Return to the caller/browser when you hit an await. await only "yields" to the ASP.NET thread pool, not to the browser.
First question is - is it good to use async action everywhere in ASP.NET MVC?
I'd say it's good to use it everywhere you're doing I/O. It may not necessarily be beneficial, though (see below).
However, it's bad to use it for CPU-bound methods. Sometimes devs think they can get the benefits of async by just calling Task.Run in their controllers, and this is a horrible idea. Because that code ends up freeing up the request thread by taking up another thread, so there's no benefit at all (and in fact, they're taking the penalty of extra thread switches)!
Shall I use async/await keywords when I want to query database (via EF/NHibernate/other ORM)?
You could use whatever awaitable methods you have available. Right now most of the major players support async, but there are a few that don't. If your ORM doesn't support async, then don't try to wrap it in Task.Run or anything like that (see above).
Note that I said "you could use". If you're talking about ASP.NET MVC with a single database backend, then you're (almost certainly) not going to get any scalability benefit from async. This is because IIS can handle far more concurrent requests than a single instance of SQL server (or other classic RDBMS). However, if your backend is more modern - a SQL server cluster, Azure SQL, NoSQL, etc - and your backend can scale, and your scalability bottleneck is IIS, then you can get a scalability benefit from async.
Third question - How many times I can use await keywords to query database asynchronously in ONE single action method?
As many as you like. However, note that many ORMs have a one-operation-per-connection rule. In particular, EF only allows a single operation per DbContext; this is true whether the operation is synchronous or asynchronous.
Also, keep in mind the scalability of your backend again. If you're hitting a single instance of SQL Server, and your IIS is already capable of keeping SQLServer at full capacity, then doubling or tripling the pressure on SQLServer is not going to help you at all.
Asynchronous action methods are useful when an action must perform several independent long running operations.
A typical use for the AsyncController class is long-running Web
service calls.
Should my database calls be asynchronous ?
The IIS thread pool can often handle many more simultaneous blocking requests than a database server. If the database is the bottleneck, asynchronous calls will not speed up the database response. Without a throttling mechanism, efficiently dispatching more work to an overwhelmed database server by using asynchronous calls merely shifts more of the burden to the database. If your DB is the bottleneck, asynchronous calls won’t be the magic bullet.
You should have a look at 1 and 2 references
Derived from #PanagiotisKanavos comments:
Moreover, async doesn't mean parallel. Asynchronous execution frees a
valuable threadpool thread from blocking for an external resource, for
no complexity or performance cost. This means the same IIS machine can
handle more concurrent requests, not that it will run faster.
You should also consider that blocking calls start with a
CPU-intensive spinwait. During stress times, blocking calls will
result in escalating delays and app pool recycling. Asynchronous calls
simply avoid this
is it good to use async action everywhere in ASP.NET MVC?
As usual in programming, it depends. There is always a trade-off when going down a certain path.
async-await shines in places where you know you'll receiving concurrent requests to your service and you want to be able to scale out well. How does async-await help with scaling out? In the fact that when you invoke a async IO call synchronously, such as a network call or hitting your database, the current thread which is responsible for the execution is blocked waiting for the request to finish. When you use async-await, you enable the framework to create a state machine for you which makes sure that after the IO call is complete, your method continues executing from where it left off.
A thing to note is that this state machine has a subtle overhead. Making a method asynchronous does not make it execute faster, and that is an important factor to understand and a misconception many people have.
Another thing to take under consideration when using async-await is the fact that it is async all the way, meaning that you'll see async penetrate your entire call stack, top to buttom. This means that if you want to expose synchronous API's, you'll often find yourself duplicating a certain amount of code, as async and sync don't mix very well.
Shall I use async/await keywords when I want to query database (via
EF/NHibernate/other ORM)?
If you choose to go down the path of using async IO calls, then yes, async-await will be a good choice, as more and more modern database providers expose async method implementing the TAP (Task Asynchronous Pattern).
How many times I can use await keywords to query database
asynchronously in ONE single action method?
As many as you want, as long as you follow the rules stated by your database provider. There is no limit to the amount of async calls you can make. If you have queries which are independent of each other and can be made concurrently, you can spin a new task for each and use await Task.WhenAll to wait for both to complete.
async actions help best when the actions does some I\O operations to DB or some network bound calls where the thread that processes the request will be stalled before it gets answer from the DB or network bound call which you just invoked. It's best you use await with them and it will really improve the responsiveness of your application (because less ASP input\output threads will be stalled while waiting for the DB or any other operation like that). In all my applications whenever many calls to DB very necessary I've always wrapped them in awaiatable method and called that with await keyword.
My 5 cents:
Use async/await if and only if you do an IO operation, like DB or external service webservice.
Always prefer async calls to DB.
Each time you query the DB.
P.S. There are exceptional cases for point 1, but you need to have a good understanding of async internals for this.
As an additional advantage, you can do few IO calls in parallel if needed:
Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result
As you know, MVC supports asynchronous controllers and you should take advantage of it. In case your Controller, performs a lengthy operation, (it might be a disk based I/o or a network call to another remote service), if the request is handled in synchronous manner, the IIS thread is busy the whole time. As a result, the thread is just waiting for the lengthy operation to complete. It can be better utilized by serving other requests while the operation requested in first is under progress. This will help in serving more concurrent requests.
Your webservice will be highly scalable and will not easily run into C10k problem.
It is a good idea to use async/await for db queries. and yes you can use them as many number of times as you deem fit.
Take a look here for excellent advise.
My experience is that today a lot of developers use async/await as a default for controllers.
My suggestion would be, use it only when you know it will help you.
The reason is, as Stephen Cleary and others already mentioned, it can introduce performance issues, rather than resolving them, and it will help you only in a specific scenario:
High-traffic controllers
Scalable backend
Is it good to use async action everywhere in ASP.NET MVC?
It's good to do so wherever you can use an async method especially when you have performance issues at the worker process level which happens for massive data and calculation operations. Otherwise, no need because unit testing will need casting.
Regarding awaitable methods: shall I use async/await keywords when I
want to query a database (via EF/NHibernate/other ORM)?
Yes, it's better to use async for any DB operation as could as possible to avoid performance issues at the level of worker processes.
Note that EF has created many async alternatives for most operations, such as:
.ToListAsync()
.FirstOrDefaultAsync()
.SaveChangesAsync()
.FindAsync()
How many times can I use await keywords to query the database
asynchronously in one single action method?
The sky is the limit

Will opening a DbContext per ToListAsync end up blocking a connection pool?

Related : EntityFramework (6) and async ( waitingForActivation)?
However, it does not address awaiting multiple items, just one. My goal was to accomplish something along these lines
var car = db.Cars.ToListAsync();
var people = db.People.ToListAsync();
Task.WhenAll(car,people);
Unfortunately I got this runtime exception (I should have known really)
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.
Database contexts aren't thread safe. Okay. So now I am considering factoring out the calls to be methods and then awaiting both method calls (or an easy way to demo this would be to just wrap each of the db calls shown above in using(db){} statements). Regardless, the problem is that with that pattern it will require a new DbContext for each ToListAsync.
Will using a DbContext per ToListAsync call be a threat to a connection pool? Is this an anti pattern?
Will using a DbContext per ToListAsync call be a threat to a connection pool?
It will use one connection per DbContext. Depending on your scenario, this may oversubscribe, or it may not. It depends a lot on the expected usage and the capabilities of your database.
Is this an anti pattern?
Not necessarily. This puts more strain on the DB, as it's going to perform both queries simultaneously. The upside is you're potentially increasing the throughput on the client side (in this case, ASP.NET being the client to the DB), which may outweigh the extra strain. Measuring is really the only way to know whether the benefits outweigh the strain on the DB.

Choosing Between WF CodeActivity and AsyncCodeActivity for DB Operations

I'm still fairly new to WF so bear with me if I don't get this worded correctly the first time. ;)
If you're doing selects against a well-normalized database, using primary keys, returning single records, in a fairly low volume environment (a few hundred requests per day), does it really make a difference whether you use CodeActivity vs AsyncCodeActivity?
While I've got some additional research to do on hosting and execution, it will be possible, but not probable, for multiple requests to be received at or near the same time. I'm not sure if that will change the answer or not.
Thanks!
Microsoft used non async in their ExecuteSqlQuery activity: http://wf.codeplex.com/releases/view/43585
Async Activities:
"This is useful for custom activities that must perform asynchronous work without holding the workflow scheduler thread and blocking any activities that may be able to run in parallel."
"As a result of going asynchronous, an AsyncCodeActivity may induce an idle point during execution. Due to the volatile nature of asynchronous work, an AsyncCodeActivity always creates a no persist block for the duration of the activity’s execution. This prevents the workflow runtime from persisting the workflow instance in the middle of the asynchronous work, and also prevents the workflow instance from unloading while the asynchronous code is executing."
Source: http://msdn.microsoft.com/en-us/library/ee358731.aspx
Edit: I noticed that only pointed out the disadvantages of using async I would consider the responses of Ron and Tim to make a better decision
In general I strongly encourage activity developers who are doing any kind of I/O to use AsyncCodeActivity and to call the underlying Async APIs whenever possible. Even if the query is short this is always preferrable.
Obviously - it's not going to make a difference unless you're actually calling an Async API inside your activity implementation.
That said, even if it makes a difference it might not make a noticeable difference in many apps. Potential reasons:
The query just runs too fast.
You aren't running multiple queries in parallel. (Running many async operations in parallel is faster than doing them synchronously and thereby sequentially.)
You don't run a large number of workflows in parallel such as would be needed to experience thread contention.

Categories