Запуск асинхронного метода в качестве задания Quartz.NET и устранение проблемы с объектом

Я использую Quartz.NET в этом контексте (необходимо отметить, что GrabberContext это DbContext расширенный класс):

// 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);

и это работа

public class GrabJob : IJob {

    private readonly IGrabService _grabService;

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

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

}

GrabService реализация примерно такая:

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);
        }
    }
}

Но когда исполнение доходит до line #1 Я получаю эту ошибку:

Экземпляр ObjectContext был удален и больше не может использоваться для операций, требующих подключения.

Любая идея, пожалуйста?

1 ответ

Решение

Вы вызываете асинхронный метод CrawlNextAsync() из метода синхронизации Execute(), Как только CrawlNextAsync() хиты...await _context..., он возвращается, и Execute() затем возвращается, и я предполагаю, что в этот момент GrabJob, и поэтому GrabService, и поэтому GrabberContext, расположен, в то время как продолжение в CrawlNextAsync() продолжается (и пытается использовать GrabberContext).

В качестве простого исправления вы можете попробовать изменить

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

в

public void Execute(IJobExecutionContext context) {
    _grabService.CrawlNextAsync("").Wait();
}
Другие вопросы по тегам