在计划作业中执行DB调用

时间:2017-12-18 12:26:04

标签: asp.net-core asp.net-core-2.0 quartz.net

我在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();

1 个答案:

答案 0 :(得分:1)

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

Documentation州:

  

当触发器触发时,将加载与其关联的JobDetail(实例定义),并通过Scheduler上配置的JobFactory实例化它引用的作业类。默认的JobFactory使用Activator.CreateInstance简单地调用作业类的默认构造函数,然后尝试在类上调用与JobDataMap中的键名匹配的setter属性。您可能希望创建自己的JobFactory实现来完成诸如让应用程序的IoC或DI容器生成/初始化作业实例之类的事情。

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

修改

此外,您可以查看我之前的answers