Hosted Services+Quartz实现定时任务调度

背景

之前.net core使用quartz.net时,总感觉非常变扭,百度和谷歌了N久都没解决以下问题,造成代码丑陋,非常不优雅:
1.项目启动时,要立刻恢复执行quartz.net中的任务
2.quartz.net中的Job任务无法使用ioc注入,要额外写一套
直到最近看到这篇文章.Net Core小技巧 - Hosted Services + Quartz实现定时任务调度,终于解决了我的问题,特此记录一下

前后代码对比

Program.cs

查看详细内容
public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();

        QuartzFactory.StartSpider();

        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

查看详细内容
class Program
{
    static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .ConfigureHostConfiguration(configHost =>
            {
                // 配置根目录
                configHost.SetBasePath(Path.GetDirectoryName(typeof(Program).Assembly.Location));
                // 读取环境变量,Asp.Net core默认的环境变量是以ASPNETCORE_作为前缀的,这里也采用此前缀以保持一致
                configHost.AddEnvironmentVariables("ASPNETCORE_");
                // 读取启动host的时候之前可传入参数
                configHost.AddCommandLine(args);
            })
            .ConfigureAppConfiguration((hostContext, configApp) =>
            {
                // 读取应用的配置json
                configApp.AddJsonFile("appsettings.json", true);
                // 读取应用特定环境下的配置json
                configApp.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", true);
                // 读取环境变量
                configApp.AddEnvironmentVariables();

            })
            .ConfigureServices((hostContext, services) =>
            {
                // 添加日志Service
                services.AddLogging();

                // 设置efcore连接字符串
                services.AddDbContext<EFContext>(options => options.UseSqlite(hostContext.Configuration.GetConnectionString("demoConnection")));

                services.AddSingleton<IJobFactory, JobFactory>();
                services.AddSingleton(provider =>
                {
                    StdSchedulerFactory factory = new StdSchedulerFactory();
                    var scheduler = factory.GetScheduler().ConfigureAwait(false).GetAwaiter().GetResult();

                    scheduler.JobFactory = provider.GetService<IJobFactory>();

                    return scheduler;
                });
                // 添加自定义的HostedService
                services.AddHostedService<DBHostedService>();
                services.AddHostedService<QuartzHostedService>();
                services.AddSingleton<TestJob, TestJob>();
            })
            .ConfigureLogging((hostContext, configLogging) =>
            {
                // 输出控制台日志
                configLogging.AddConsole();
                // 输出Debug日志
                configLogging.AddDebug();
            })
            // 使用控制台生命周期
            .UseConsoleLifetime()
            .Build();
        await host.RunAsync();
    }
}

Job

查看详细内容
public class SpiderJob : IJob
{
    public async Task Execute(IJobExecutionContext context)
    {
        using (var ctx = new EfContext()) 
        {
            var list = await ctx.Goods.AsNoTracking().ToListAsync();
        }
    }
}

查看详细内容
public class TestJob : IJob
{
    private readonly ILogger _logger;
    private readonly IConfiguration _config;
    private readonly EFContext _context;

    public TestJob(ILogger<TestJob> logger, IConfiguration config, EFContext context)
    {
        _logger = logger;
        _config = config;
        _context = context;

    }

    public async Task Execute(IJobExecutionContext context)
    {
        _logger.LogInformation(string.Format("[{0:yyyy-MM-dd hh:mm:ss:ffffff}]任务执行!", DateTime.Now));

        // 读取配置
        Console.WriteLine($"读取配置{ _config["test"] }");

        // 读取数据库
        var model = await _context.QuartInfo.FirstOrDefaultAsync();
        if (model != null)
        {
            Console.WriteLine($"读取数据库 { model.jobName }");
        }
    }
}

Demo地址:https://gitee.com/kw13202/HostedServiceDemo

posted @ 2019-04-05 23:41  爱幻想の宅  阅读(636)  评论(0编辑  收藏  举报