Cannot access a disposed object

Hi i just setup Hangfire in a aspnet core project with AutoFac.

But i got this problem when running a RecurringJob.

“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 is 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.”

My setup:
var builder = new ContainerBuilder(); builder.RegisterType<BookingCalendarDbContext>().InstancePerLifetimeScope(); builder.Populate(services); var container = builder.Build(); GlobalConfiguration.Configuration.UseAutofacActivator(container, false)

1 Like

Hi, can you post the stack trace here?

Message: 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 is 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: ‘BookingCalendarDbContext’.

StackTrace: 
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.DbContext.get_StateManager()
   at Microsoft.EntityFrameworkCore.DbContext.EntryWithoutDetectChanges[TEntity](TEntity entity)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
   at BookingCalendar.Data.CalendarCore.Repositories.CalendarEventRepository.Add(CalendarEvent calendarEvent) in C:\Code\BookingCalendar\src\BookingCalendar.Data\CalendarCore\Repositories\CalendarEventRepository.cs:line 59
   at BookingCalendar.Core.CalendarCore.Services.Implementation.CalendarEventService.Create(CalendarEvent calendarEvent) in C:\Code\BookingCalendar\src\BookingCalendar.Core\CalendarCore\Services\Implementation\CalendarEventService.cs:line 21
   at BookingCalendar.Core.CalendarCore.Services.Implementation.CalendarICalService.AddOrUpdateICalEvents(CalendarICal iCal, IReadOnlyList`1 existingCalendarEventsToProcess, IReadOnlyList`1 existingCalendarEventsWithICalToProcess, IReadOnlyList`1 newICalEvents) in C:\Code\BookingCalendar\src\BookingCalendar.Core\CalendarCore\Services\Implementation\CalendarICalService.cs:line 159
   at BookingCalendar.Core.CalendarCore.Services.Implementation.CalendarICalService.ImportEvents(CalendarICal iCal, IReadOnlyList`1 calendarEvents, IReadOnlyList`1 newICalEvents) in C:\Code\BookingCalendar\src\BookingCalendar.Core\CalendarCore\Services\Implementation\CalendarICalService.cs:line 115
   at BookingCalendar.Core.CalendarCore.Services.Implementation.CalendarICalService.<>c__DisplayClass3_0.<<Import>b__0>d.MoveNext() in C:\Code\BookingCalendar\src\BookingCalendar.Core\CalendarCore\Services\Implementation\CalendarICalService.cs:line 32

Do you see this exception on the job details/failed jobs page? Can you show me the source code of your BookingCalendarDbContext method?

No there is no exception in jobs dashboard, because the application fails and closes.

public class BookingCalendarDbContext : IdentityDbContext<User> { public BookingCalendarDbContext(DbContextOptions<BookingCalendarDbContext> options) : base(options) { }

@fatihk, really sorry, I wanted to ask about source code of the recurring job that is failing to know how do you pass the dependencies, but copy-pasted the BookingCalendarDbContext :slight_frown:

It is okay,

RecurringJob.AddOrUpdate<ICalendarICalService>(x => x.Import(request.CalendarId), Cron.MinuteInterval(15));

When i run the job from the hangfire dashboard it is hitting the right service and so on, the problem is when i call a certain repository and try to save something to the database then it is saying that the DbContext is disposed. I assume it is something with the setup?

How does the implementation of the ICalendarICalService interface looks like? How do you pass the dbcontext dependency?

It has a constructor with two parameters that are interfaces calling a repository that uses the dbcontext.

private BookingCalendarDbContext _db; public CalendarEventRepository(BookingCalendarDbContext db) { _db = db; }

Still can’t reproduce the issue. Do you return anything from the Import method? Can you post here its source code?

The method does not return something it is something with the setup with the DbContext. Maybe you have a way to setup with Autofac? @odinserj

The BookingCalendarDbContext service registration is ok (InstancePerLifetimeScope). Hangfire.Autofac will create a new scope before executing just another background job, and will dispose the scope (and dispose the db context) just after the processing.

How the implementation of the ICalendarICalService interface is registered? If you are using singleton registration, then you’ll end up with exactly your problem, because there will be only 1 shared object with a disposed database context.

This is the setup of the services and repositories.

            var builder = new ContainerBuilder();
            builder.RegisterType<BookingCalendarDbContext>().InstancePerLifetimeScope();
            builder.RegisterType<PlanRepository>().As<IPlanRepository>().InstancePerLifetimeScope();
            builder.RegisterType<CalendarRepository>().As<ICalendarRepository>().InstancePerLifetimeScope();
            builder.RegisterType<CalendarEventRepository>().As<ICalendarEventRepository>().InstancePerLifetimeScope();
            builder.RegisterType<CalendarICalService>().As<ICalendarICalService>().InstancePerLifetimeScope();

            builder.RegisterType<StripeSubscriptionService>().As<ISubscriptionService>().InstancePerLifetimeScope();
            builder.RegisterType<PlanService>().As<IPlanService>().InstancePerLifetimeScope();
            builder.RegisterType<CalendarService>().As<ICalendarService>().InstancePerLifetimeScope();
            builder.RegisterType<CalendarEventService>().As<ICalendarEventService>().InstancePerLifetimeScope();
            builder.RegisterType<CalendarApiService>().AsSelf().InstancePerLifetimeScope();
            builder.RegisterType<CalendarEventApiService>().AsSelf().InstancePerLifetimeScope();

Can you debug this by setting a breakpoint on BookingCalendarDbContext.Dispose method and post here the stack trace?

I called the BookingCalendarDbContext inside a constructor with .Dispose() like this.
public CalendarEventRepository(BookingCalendarDbContext db) { _db = db; _db.Dispose(); }

StackTrace

@odinserj I found the problem, it was because i was doing some async work in my service and i haven’t applied async to the method that was called from the RecurringJob it is now working.

1 Like

This answer just saved me a whole lot. Thanks