David
David

Reputation: 3157

Asp.net Core + Hangfire ends up with closed or disposed connection

I am using latest Hangfire v1.6 with an asp.net core 2.1 site. I am using Entity Framework core 2.1

I submit a job to hangfire but I am ending up with errors like my connection is closed or has been disposed.

The exception when ...

2018-10-25 21:35:29.1990|[]|10100|ERROR|Microsoft.EntityFrameworkCore.Query|An exception occurred in the database while iterating the results of a query for context type 'OmniService.DataAccess.Models.OmniServiceDbContext'. System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'AsyncDisposer'....

I am using Microsoft DI (not autofac) and it seems the only way that I can keep my connection open is to set it up as a Singleton. Once I do this I see errors that context is tracking an instance that already exists...of course i can ensure that no tracking is used however this seems like it not the solution.

i.e.

The instance of entity type 'PostedData' cannot be tracked because another instance with the same key value for {'SubmitId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

In terms of setting up dbcontext

//hangfire
services.AddHangfire(x => x.UseSqlServerStorage(connectionString));
services.AddDbContext<OmniServiceDbContext>(options => 
        options.UseSqlServer(Configuration.GetSection("ConnectionStrings:ConnectionString").Value), ServiceLifetime.Transient);

services.AddTransient(typeof(IPostedDataService), typeof(PostedDataService));
services.AddSingleton<IConfiguration>(Configuration);

So, what I am missing is why does hangfire not like my transient services with respect to dbcontext?

Upvotes: 1

Views: 1932

Answers (1)

David
David

Reputation: 3157

Found my answer with the help of the post below. I had thought I had missed some Hangfire configuration. In fact I made this change

OLD

public async void ProcessPostedData(Guid submitId, int retry = 0)

WORKING

public async Task ProcessPostedData(Guid submitId, int retry = 0)

I was calling an async method returning void when it should have been Task. I hope this helps someone else save 3 hours.

Cannot access a disposed object Asp.net Identity Core

Upvotes: 5

Related Questions