Hi.
I just updated from 5.0.0-preview.7.20365.15 to 5.0.0-preview.8.20407.4 and now get the following error:
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IResettableService.ResetStateAsync(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.ReturnAsync(IDbContextPoolable context, CancellationToken cancellationToken)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.<DisposeAsync>g__Await|15_0(Int32 i, ValueTask vt, List`1 toDispose)
at Microsoft.AspNetCore.Http.Features.RequestServicesFeature.<DisposeAsync>g__Awaited|9_0(RequestServicesFeature servicesFeature, ValueTask vt)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.FireOnCompletedAwaited(Task currentTask, Stack`1 onCompleted)
This happens when an endpoint is called. I can see that it executes the endpoint, so this probably happens when it's cleaning things up (it's no longer in my user code). My context is pooled as it says in the stack trace. Happens with both SQLite and AzureSQL providers so it's probably not provider dependent. I had no problems with 5.0.0-preview.7.20365.15.
I have to roll back to 5.0.0-preview.7.20365.15 for now until this is fixed, but want to be proactive on this so that the next version would work again.
EF Core version: 5.0.0-preview.8.20407.4
Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer) SQLite, AzureSQL
Target framework: (e.g. .NET Core 3.0) .NET Core 3.1
Operating system: OS X
IDE: (e.g. Visual Studio 2019 16.3) Visual Studio for Mac 8.7.4
@Tommigun1980 @slubowsky @julitogtu @MateuszBogdan We have not been able to reproduce this. Would it be possible to attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate?
@Tommigun1980 @slubowsky @julitogtu @MateuszBogdan We have not been able to reproduce this. Would it be possible to attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate?
Hi @ajcvickers. I don't think it's possible for me to start isolating exactly why it happens as my project is somewhat large and it could take me hours to isolate exactly what's wrong. Do you have a private ftp server (or similar) at Microsoft where I could upload my project, possibly with an NDA, so you could just run it? It should be really easy to reproduce it with my repo as you literally just run it and then you could curl into an endpoint to get it to happen.
Unless someone else has a repro case, of course.
Thanks.
@Tommigun1980 You can email it to me (I'm avickers at microsoft dot com) and we will keep it private.
@Tommigun1980 You can email it to me (I'm avickers at microsoft dot com) and we will keep it private.
Could you maybe try this first, and if you can't repro I'll mail it to you?
```c#
Action
// this won't work
services.AddDbContextPool
options.UseSqlite(configuration.GetConnectionString("NameOfDatabase"), SetProviderOptions));
// this will work
services.AddDbContext
options.UseSqlite(configuration.GetConnectionString("NameOfDatabase"), SetProviderOptions));
```
The same happens with options.UseSqlServer, so I would assume it's not provider dependent. My context doesn't have anything special in it, except that it is polymorphic - ie it derives from a base context, but I don't think that matters here.
The end point is a normal controlle endpoint, that calls into a dependency injected service. The service dependency injects the context.
When the endpoint is invoked, it runs fine, but then the aforementioned error happens when it's I am presuming exiting the endpoint.
If I replace my services.AddDbContextPool with services.AddDbContext then the error goes away.
@ajcvickers I think I figured it out. The problem is accessing a pooled Db context inside an ActionFilterAttribute.
The endpoint in question (and almost all of my endpoints) do authentication things inside an ActionFilterAttribute. Said attribute fetches the context as such (as there's no DI in attributes):
c#
context.HttpContext.RequestServices.GetService<IMyDatabase>();
...and both reads from and writes to it. If I either remove the attribute, or make the contexts pooled, it works.
So the issue is "accessing pooled database contexts inside attributes no longer works".
Hope this helps and let me know if you still need the project if you are unable to repro it.
@ajcvickers The same problem seems to happen with SignalR in preview 8 as well - ie using pooled db contexts gives the following error on the server when a user connects to a hub:
Microsoft.AspNetCore.SignalR.HubConnectionHandler: Error: Error when dispatching 'OnConnectedAsync' on hub.
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IResettableService.ResetStateAsync(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.ReturnAsync(IDbContextPoolable context, CancellationToken cancellationToken)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.<DisposeAsync>g__Await|15_0(Int32 i, ValueTask vt, List`1 toDispose)
at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnConnectedAsync(HubConnectionContext connection)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.RunHubAsync(HubConnectionContext connection)
I am filing it here because the root cause is probably the same, and this error also goes away when using non-pooled db contexts. My hub's OnConnectedAsync calls into a service that does similar authentication as the attribute, but this time using DI (which is available here).
So...
"Pooled db contexts crash on cleanup when used inside action attributes, and when accessed in SignalR hubs"
@Tommigun1980 Is it possible that either:
(Both of these things are not allowed.)
@Tommigun1980 Is it possible that either:
- The same context instance is being used concurrently from different threads?
- The context instance is being used after being returned to the pool when the service scope is disposed?
(Both of these things are not allowed.)
Hi @ajcvickers. No it should not be possible (well everything is technically possible but it's written in a way that it shouldn't happen). Everything worked fine up 'til preview 7. Do you think this is enough for reproing or do you still want my project?
I can confirm as well as I'm seeing the same behaviour on preview 8 that is remedied by downgrading to preview 7. Attached is a minimal project that exhibits the issue. Just hit the /weatherforecast endpoint to reproduce (eg: curl --insecure -X GET https://localhost:5001/weatherforecast).
Changing <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.0-preview8" /> to <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.0-preview7" /> resolves the issue.
Thanks @leitneier. PR is out to fix this for RC1; will probably be in the daily build tomorrow or Monday.
Workaround is to use AddDbContext instead of AddDbContextPool.
Thanks @leitneier. PR is out to fix this for RC1; will probably be in the daily build tomorrow or Monday.
Workaround is to use
AddDbContextinstead ofAddDbContextPool.
Great turnaround, thanks so much for fixing this!
Most helpful comment
Thanks @leitneier. PR is out to fix this for RC1; will probably be in the daily build tomorrow or Monday.
Workaround is to use
AddDbContextinstead ofAddDbContextPool.