-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. #21987
Comments
You are not correctly using async/await. Change the SetupViewBags signature from Then in your controller, properly await it and change the controller action signature as following: public async Task<IActionResult> Create()
{
await SetupViewBags();
return View();
} Furthermore you should not block in GetNotificationsCount. Use var userId = await GetCurrentTennantId();
return await _context.Notifications.Where(w => w.SharedTo == userId.ToString()).CountAsync(); Check your other code for these patterns and fix accordingly. |
I had the same error using ef-core in wpf with autofact. if using Ctor injection in wpf the issue seems to go away if I inject a Func in the constructor rather than injecting repository |
@andersonphiri Yes the problem is autofac. The problem was fixed when Autofac did InstancePerLifetimeScope () instead of SingleInstance (). Thanks for your answer. |
i have a list task that i finally await to get the result. it worked fine with efcore 2.1. today i updated my project to .NET 5. im using EF core 5. im getting the error "A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext".
please help @roji |
hi @tnlthanzeel DbContext is not thread safe. it is recommended to use DI then do a ctor Injection. Dont forget to register in startup CS file. If you don't mind, please share the repo then i checkout your code and see if I can re-create and fix. |
hi @andersonphiri , thanks for the response. the repo is private. this is the Startup.cs setup as follows
i have injected the dbcontext in the constructor using DI
this has been working well on ef core 2.1 i tried with Transient scope as well. but still fails with same error |
I see. then execute your tasks in sequence. I suspect there is one spot where your queries are overlapping on a particular entity. |
yes, executing tasks in sequence worked. but i want to make use of the Task.WhenAll() as i have been using in ef core 2.1. please help all the 3 methods have three different entities |
try inject multiple dbCOntexts maybe you can win this race condition issue. but watch out for DbUpdateException |
each service has its own dbcontext injected in the ctor |
i found have a place where one of my team mate has added
so now i removed it and the Task.WhenAll() works only under transient ServiceLifetime. why does it not work in scoped ServiceLifetime as in ef core 2.1? please help @ErikEJ |
Maybe you were not running the query on the database with EF Core 2.1? |
hi sir. it has been running on production with ef core 2.1 for 3 years. here is a similar issue with ef core with MySql PomeloFoundation/Pomelo.EntityFrameworkCore.MySql#1023 im just curios if this issue was in ef core 2.1 https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/#avoiding-dbcontext-threading-issues and was not addressed? please help me @roji |
@tnlthanzeel what @lauxjpn writes in PomeloFoundation/Pomelo.EntityFrameworkCore.MySql#1023 is fully right - EF Core has never supported using the same DbContext instance concurrently from multiple threads. Some code using concurrent access may have accidentally worked in some situations, but only because it happened to not trigger an exception due to timing. You'll have to ensure that you're not using the instance concurrently, either by serializing your queries, or by using multiple DbContext instances (which would represent multiple database connections). If you'd like to pursue this further, we need a minimal, runnable code sample. |
If you inject a On the other hand, if you register your @tnlthanzeel If your code runs fine with the transient approach, then consider using it. Another way to achieve the same would be to keep the I am curious what your reason for your optimization is:
(Because there might be better solutions to the underlying problem, depending on what it actually is.) |
Just to add to @lauxjpn great response above, if you generally want to keep DbContext as Scoped, you can still get injected with an IDbContextFactory in the specific place where you need multiple instances (see the docs). That would probably be a bit easier/cleaner than creating DI scopes yourself. |
@roji Nice one! I'll keep that in mind for my own projects :) |
Hi @roji , i understand. but the same code doesnt work with EF Core 5 which worked in EF Core 2.1. Here is a a repo with minimul code which runs fine on EF Core 2.1 https://github.com/tnlthanzeel/EFCore-TaskWhenAll. Swagger is installed. go to http://localhost:{yourportnumber}/swagger |
Hi @lauxjpn , thanks for sharing your knowledge. the web server and the db server are on the same location. What i did was to implement Task.WhenAll() which i learnt. i applied the theory which i thought was a best place to apply. |
@tnlthanzeel I see. There are many technologies that work well with that approach, but since a (In my personal experience, simplicity is usually the greatest quality that source code can provide, because it positively effects the app in so many different ways. Once simplicity is gone, it will be much harder later to get it back again.) |
@lauxjpn thanks for the advice. no i understand better. i never knew the fact we cannot use parallel programming on a dbcontext. just cam to know that just within 24 hours. thanks again sir |
I wanted to add that in my case I forgot to await _userManager.FunctionAsync(). So if you are having this error have a look around if you have put your await everywhere. ;) |
@upizs If you are calling an |
That is telling you that there are unnecessary requests that are been sent to the DbContext |
I am using ef core 3.1.5 and asp.net core 3.1 and am having this constant issue around a function that sets a view bag in the edit and create methods.
Strange thing is this only happens in production on the hosted server, i dont get this error locally
This setup view bag would be called on functions like edit and create
For Example I would call it as such
Got Exceptions? Include both the message and the stack trace
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 165.3482ms 200 application/javascript
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[@__ToString_0='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM [MISobject] AS [m]
WHERE (([m].[OIC_1] = @__ToString_0) OR ([m].[OIC_2] = @__ToString_0)) AND (([m].[isDeleted] = CAST(0 AS bit)) AND ([m].[isActive] = CAST(1 AS bit)))
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 163.0282ms 200 application/javascript
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [a].[FirstName], [a].[LastName], [a].[Id]
FROM [AspNetUsers] AS [a]
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [a].[Id], [a].[AccessFailedCount], [a].[ConcurrencyStamp], [a].[Email], [a].[EmailConfirmed], [a].[FirstName], [a].[LastName], [a].[LockoutEnabled], [a].[LockoutEnd], [a].[NormalizedEmail], [a].[NormalizedUserName], [a].[PasswordHash], [a].[PhoneNumber], [a].[PhoneNumberConfirmed], [a].[SecurityStamp], [a].[TennantId], [a].[TwoFactorEnabled], [a].[UserName]
FROM [AspNetUsers] AS [a]
fail: Microsoft.EntityFrameworkCore.Query[10100]
An exception occurred while iterating over the results of a query for context type 'MISSystem.Dal.MISDBContext'.
System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.AsyncEnumerator.MoveNextAsync() System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913. at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection() at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.AsyncEnumerator.MoveNextAsync()info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
Sending file. Request path: '/font-awesome/js/all.js'. Physical path: 'D:\GitMaster\MIS\uno\MISSystem.WEB\MISSystem.Web\MISSystem.Web\wwwroot\font-awesome\js\all.js'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
For
dotnet ef
and PMC, share the --verbose outputAn exception occurred while iterating over the results of a query for context type 'MISSystem.Dal.MISDBContext'.
System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.Enumerator.MoveNext() System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913. at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection() at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.Enumerator.MoveNext()Unhandled exception. System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.Enumerator.MoveNext() at System.Linq.Enumerable.Single[TSource](IEnumerable
1 source)at lambda_method(Closure , QueryContext )
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Count[TSource](IQueryable
1 source) at MISSystem.Web.Controllers.MISObjectsController.GetNotificationsCount() in D:\GitMaster\MIS\uno\MISSystem.WEB\MISSystem.Web\MISSystem.Web\Controllers\MISObjectsController.cs:line 115 at MISSystem.Web.Controllers.MISObjectsController.SetupViewBags() in D:\GitMaster\MIS\uno\MISSystem.WEB\MISSystem.Web\MISSystem.Web\Controllers\MISObjectsController.cs:line 405 at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__139_1(Object state) at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi) at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action
1 callback, TState& state)at System.Threading.QueueUserWorkItemCallback.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
Further technical details
EF Core version:
Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer)
Target framework: (e.g. .NET Core 3.0)
Operating system:
IDE: (e.g. Visual Studio 2019 16.3)
The text was updated successfully, but these errors were encountered: