3

I'm using Quartz.NET in this context (needs to mention that GrabberContext is a DbContext extended class):

// configuring Autofac:
var builder = new ContainerBuilder();

// configuring GrabberContext
builder.RegisterType<GrabberContext>()
    .AsSelf()
    .InstancePerLifetimeScope();

// configuring GrabService
builder.RegisterType<GrabService>()
    .AsImplementedInterfaces()
    .InstancePerLifetimeScope();

// configuring Quartz to use Autofac
builder.RegisterModule(new QuartzAutofacFactoryModule());
builder.RegisterModule(new QuartzAutofacJobsModule(typeof(DiConfig).Assembly));

var container = builder.Build();

// configuring jobs:
var scheduler = container.Resolve<IScheduler>();
scheduler.Start();
var jobDetail = new JobDetailImpl("GrabJob", null, typeof(GrabJob));
var trigger = TriggerBuilder.Create()
    .WithIdentity("GrabJobTrigger")
    .WithSimpleSchedule(x => x
        .RepeatForever()
        .WithIntervalInMinutes(1)
    )
    .StartAt(DateTimeOffset.UtcNow.AddSeconds(30))
    .Build();
    scheduler.ScheduleJob(jobDetail, trigger);

and this is the job:

public class GrabJob : IJob {

    private readonly IGrabService _grabService;

    public GrabJob(IGrabService grabService) { _grabService = grabService; }

    public void Execute(IJobExecutionContext context) {
        _grabService.CrawlNextAsync("");
    }

}

The GrabService implementation is something like this:

public class GrabService : IGrabService {

    private readonly GrabberContext _context;

    public GrabService(GrabberContext context) {
        _context = context;
    }

    public async Task CrawlNextAsync(string group) {
        try {
            var feed = await _context.MyEntities.FindAsync(someId); // line #1
            // at the line above, I'm getting the mentioned error...
        } catch(Exception ex) {
            Trace.WriteLine(ex.Message);
        }
    }
}

But when the execution gets to line #1 I get this error:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

Any idea please?

amiry jd
  • 27,021
  • 30
  • 116
  • 215

1 Answers1

5

You're calling the async method CrawlNextAsync() from a sync method Execute(). As soon as CrawlNextAsync() hits ...await _context..., it returns, and Execute() then returns, and I assume at that point the GrabJob, and hence GrabService, and hence GrabberContext, is disposed, while the continuation in CrawlNextAsync() continues (and tries to use the disposed GrabberContext).

As a simple fix, you could try change

public void Execute(IJobExecutionContext context) {
    _grabService.CrawlNextAsync("");
}

to

public void Execute(IJobExecutionContext context) {
    _grabService.CrawlNextAsync("").Wait();
}
sellotape
  • 8,034
  • 2
  • 26
  • 30