在计划作业中执行数据库调用

Execute DB call within Scheduled Job

我在 ASP Core 2 下构建了一个项目,该项目使用 Quartz.NET 调度程序 3-beta1

我有以下要执行的工作:

public class TestJob: IJob
{
    private readonly AppDbContext _dbContext;
    public TestJob(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public Task Execute(IJobExecutionContext context)
    {
        Debug.WriteLine("Test check at " + DateTime.Now);

        var testRun = _dbContext.TestTable.Where(o => o.CheckNumber > 10).ToList();

        Debug.WriteLine(testRun.Count);

        return Task.CompletedTask;
    }
}

不幸的是,它永远不会工作,也没有错误日志来指示问题。

然而,当我删除所有内容并保留 Debug.WriteLine 时,它会按照下面的示例工作。

public class TestJob: IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            Debug.WriteLine("Test check at " + DateTime.Now);

            return Task.CompletedTask;
        }
    }

我怎样才能让我的作业执行数据库调用?

编辑 1:创造就业机会

var schedulerFactory = new StdSchedulerFactory(properties);
            _scheduler = schedulerFactory.GetScheduler().Result;
            _scheduler.Start().Wait();

var testJob = JobBuilder.Create<TestJob>()
    .WithIdentity("TestJobIdentity")
    .Build();
var testTrigger = TriggerBuilder.Create()
    .WithIdentity("TestJobTrigger")
    .StartNow()
    .WithSimpleSchedule(x => x.WithIntervalInMinutes(1).RepeatForever())
    .Build();


if (CheckIfJobRegistered(testJob.Key).Result == false)
    _scheduler.ScheduleJob(testJob, testTrigger).Wait();

这里的主要问题是 Quartz 无法创建作业并吞下异常。

Documentation 状态:

When a trigger fires, the JobDetail (instance definition) it is associated to is loaded, and the job class it refers to is instantiated via the JobFactory configured on the Scheduler. The default JobFactory simply calls the default constructor of the job class using Activator.CreateInstance, then attempts to call setter properties on the class that match the names of keys within the JobDataMap. You may want to create your own implementation of JobFactory to accomplish things such as having your application’s IoC or DI container produce/initialize the job instance.

Quartz 提供了 IJobFactory 来实现这一点。它与依赖注入一起工作得非常好。 JobFactory 可以如下所示:

public class JobFactory : IJobFactory
{
    //TypeFactory is just the DI Container of your choice
    protected readonly TypeFactory Factory;

    public JobFactory(TypeFactory factory)
    {
        Factory = factory;
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        try
        {
            return Factory.Create(bundle.JobDetail.JobType) as IJob;
        }
        catch (Exception e)
        {
            //Log the error and return null
            //every exception thrown will be swallowed by Quartz 
            return null;
        }
    }

    public void ReturnJob(IJob job)
    {
        //Don't forget to implement this,
        //or the memory will not released
        Factory.Release(job);
    }
}

然后只需将您的 JobFactory 注册到调度程序,一切都会正常工作:

_scheduler.JobFactory = new JobFactory(/*container of choice*/);

编辑:

另外你可以看看我之前的一篇.