千家信息网

.NET Core开发Windows服务之怎么使用Quartz执行定时任务

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍".NET Core开发Windows服务之怎么使用Quartz执行定时任务",在日常操作中,相信很多人在.NET Core开发Windows服务之怎么使用Quartz执行定时任务问题
千家信息网最后更新 2026年11月02日.NET Core开发Windows服务之怎么使用Quartz执行定时任务

这篇文章主要介绍".NET Core开发Windows服务之怎么使用Quartz执行定时任务",在日常操作中,相信很多人在.NET Core开发Windows服务之怎么使用Quartz执行定时任务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答".NET Core开发Windows服务之怎么使用Quartz执行定时任务"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

最近的项目也是主要为团队提供API接口,大多都是处理常规的业务逻辑上的事。过程中有个需求是需要每日定时定点执行一些推送消息的任务,一开始也没多想就将定时任务写到了API的项目里,部署完测试下人傻了,日志没有任何执行了任务的痕迹,调试时候没毛病。回头一想,IIS这个懒东西应该是休眠了,直接把我的任务一起回收掉了。淡定的我捋了捋思绪查了查方案,可以更改IIS设置修改定时回收的模式,可以通过访问站点来唤醒,觉得不是很合适,既然是WindowsServer,那我干脆弄一个WindowsService来定时执行任务再好不过了鸭,而且之前也没用过.net core写过WindowsService,正好吃个螃蟹。

一开始我是直接弄了个控制台程序,按照之前.NET Framework的写法来写。后来发现.NET Core专门为这种后台服务(长时间运行的服务)设计了项目模板,称之为Worker Service。为了满足在每日的固定时间点执行,这里选择老牌的Quartz来实现。简单描述一下Demo要实现的需求:每日定点向一个API接口中发送信息。

使用Visual Studio(我是使用的VS2019)创建项目,选择Worker Service(如下图),姑且就命名为WindowsServiceDemo。

项目创建完成之后里面的内容很简单,一个Program.cs和另一个Work.cs,Work类继承BackgroundService,并重写其ExecuteAsync方法。显而易见,ExecuteAsync方法就是执行后台任务的入口。

Program.cs中,依旧是类型的通过创建一个IHost并启动运行。为了方便进行依赖注入,可以创建一个IServiceCollection的扩展方法来进行服务的注册,接下来一步步介绍。

进行服务注册之前,先将需要引用的包通过Nuget安装一下。安装 Quartz 来实现定时执行任务。另外由于需求需要调用api接口即需要使用HttpClient发送请求,所以还需要另外引入包 Microsoft.Extentsions.Http 。由于需要部署成WindowService,需要引入包 Microsoft.Extensions.Hosting.WindowsServices 。

首先定义Job,即执行任务的具体业务逻辑。创建一个SendMsgJob类,继承IJob接口,并实现Execute方法。Execute方法就是到了设定好的时间点时执行的方法。这里即是实现了使用注册的HttpClient来发送消息的过程。

public class SendMsgJob : IJob{    private readonly AppSettings _appSettings;    private const string ApiClientName = "ApiClient";    private readonly IHttpClientFactory _httpClientFactory;    private readonly ILogger _logger;    public SendMsgJob(IHttpClientFactory httpClientFactory, IOptions appSettings, ILogger logger)    {        _httpClientFactory = httpClientFactory;        _logger = logger;        _appSettings = appSettings.Value;    }    ///     /// 定时执行    ///     ///     ///     public async Task Execute(IJobExecutionContext context)    {        _logger.LogInformation($"开始执行定时任务");        //从httpClientFactory获取我们注册的named-HttpClient        using var client = _httpClientFactory.CreateClient(ApiClientName);        var message = new        {        title = "今日消息",        content = _appSettings.MessageNeedToSend        };        //发送消息        var response = await client.PostAsync("/msg", new JsonContent(message));        if (response.IsSuccessStatusCode)        {            _logger.LogInformation($"消息发送成功");        }    }}

创建好Job之后,便是设置它让其定时执行即可。来到Work.cs,替换掉原来的默认演示代码,换之配置Job执行策略的代码。使用Quartz配置Job大致分为这么几部

  1. 创建调度器 Scheduler

  2. 创建Job实例

  3. 创建触发器来控制Job的执行策略

  4. 将Job实例和触发器实例配对注册进调度器中

  5. 启动调度器

public class Worker : BackgroundService{    private readonly ILogger _logger;    public Worker(ILogger logger)    {        _logger = logger;    }    protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        _logger.LogInformation("服务启动");        //创建一个调度器        var scheduler = await StdSchedulerFactory.GetDefaultScheduler(stoppingToken);        //创建Job        var sendMsgJob = JobBuilder.Create()        WithIdentity(nameof(SendMsgJob), nameof(Worker))        Build();        //创建触发器        var sendMsgTrigger = TriggerBuilder.Create()        WithIdentity("trigger-" + nameof(SendMsgJob), "trigger-group-" + nameof(Worker))        StartNow()        WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(08, 30)) //每日的08:30执行        Build();        await scheduler.Start(stoppingToken);        //把Job和触发器放入调度器中        await scheduler.ScheduleJob(sendMsgJob, sendMsgTrigger, stoppingToken);    }}

关于定时任务的配置告一段落,接下来将所需的服务注册到服务容器中。根据之前所说的,我们创建一个扩展方法来管理我们需要注册的服务。

public static class DependencyInject{    ///     /// 定义扩展方法,注册服务    ///     public static IServiceCollection AddMyServices(this IServiceCollection services, IConfiguration config)    {        //配置文件        services.Configure(config);        //注册"命名HttpClient",并为其配置拦截器        services.AddHttpClient("ApiClient", client =>        {            client.BaseAddress = new Uri(config["ApiBaseUrl"]);        }).AddHttpMessageHandler(_ => new AuthenticRequestDelegatingHandler());        //注册任务        services.AddSingleton();        return services;    }}

修改Program.cs,调用新增的扩展方法

namespace WindowsServiceDemo{    public class Program    {        public static void Main(string[] args)        {            CreateHostBuilder(args).Build().Run();        }        public static IHostBuilder CreateHostBuilder(string[] args) =>            Host.CreateDefaultBuilder(args)            ConfigureServices((hostContext, services) =>            {                //注册服务                services.AddMyServices(hostContext.Configuration)                AddHostedService();            });    }}

到此,主要的代码就介绍完了。为了调试,可以修改设定好的定时执行时间(比如一分钟之后),来测试是否能够成功。修改完触发器的触发时间后,直接运行项目。但是遗憾的是,任务并没有定时触发。这是什么原因呢?其实是因为虽然我们将我们自定义的Job注入的服务容器,但是调度器创建Job实例时,并不是从我们的服务容器去取的,而是调度器自己走默认的实例化。解决方法是我们为调度器指定JobFactory来重写实例化Job类型的规则。

首先创建一个MyJobFactory并继承IJobFactory接口,实现方法 NewJob ,这个方法便是工厂实例化Job的方法,我们可以在这里将实例化Job的方式改写成从服务容器中获取实例的方式。

namespace WindowsServiceDemo{    ///     /// Job工厂,从服务容器中取Job    ///     public class MyJobFactory : IJobFactory    {        protected readonly IServiceProvider _serviceProvider;        public MyJobFactory(IServiceProvider serviceProvider)        {            _serviceProvider = serviceProvider;        }        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)        {            var jobType = bundle.JobDetail.JobType;            try            {                var job = _serviceProvider.GetService(jobType) as IJob;                return job;            }            catch (Exception e)            {                Console.WriteLine(e);                throw;            }        }        public void ReturnJob(IJob job)        {            var disposable = job as IDisposable;            disposable?.Dispose();        }    }}

随后将 MyJobFactory 也注册到服务容器中,即在 AddMyServices 扩展方法中添加

1 //添加Job工厂2 services.AddSingleton();

接下来将调度器的Factory替换成 MyJobFactory ,修改Work.cs代码如下。

public class Worker : BackgroundService{    private readonly ILogger _logger;    private readonly MyJobFactory _jobFactory;    public Worker(ILogger logger, MyJobFactory jobFactory)    {        _logger = logger;        _jobFactory = jobFactory;    }    protected override async Task ExecuteAsync(CancellationToken stoppingToken)    {        _logger.LogInformation("服务启动");        //创建一个调度器        var scheduler = await StdSchedulerFactory.GetDefaultScheduler(stoppingToken);        //指定自定义的JobFactory        scheduler.JobFactory = _jobFactory;        //创建Job        var sendMsgJob = JobBuilder.Create()        WithIdentity(nameof(SendMsgJob), nameof(Worker))        Build();        //创建触发器        var sendMsgTrigger = TriggerBuilder.Create()        WithIdentity("trigger-" + nameof(SendMsgJob), "trigger-group-" + nameof(Worker))        StartNow()        WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(08, 30)) //每日的08:30执行        Build();        await scheduler.Start(stoppingToken);        //把Job和触发器放入调度器中        await scheduler.ScheduleJob(sendMsgJob, sendMsgTrigger, stoppingToken);    }}

在此执行调试,现在一旦到达我们在触发器中设置的时间点, SendMsgJob 的 Execute 方法便会成功触发。

开发完成后,现在剩下的任务就是如何将项目发布成一个WindowsService。来到 Program.cs 下,需要进行一些改动

 public static IHostBuilder CreateHostBuilder(string[] args) =>     Host.CreateDefaultBuilder(args)         .UseWindowsService()    //按照Windows Service运行 .ConfigureServices((hostContext, services) =>         {             //注册服务             services.AddMyServices(hostContext.Configuration)                     .AddHostedService();         });

重新编译项目成功后,我们便可以使用sc.exe来部署成为windows服务。以管理员身份启动命令行,执行

> sc.exe create WindowsServiceDemo binPath="D:\workspace\WindowsServiceDemo\WindowsServiceDemo\bin\Debug\netcoreapp3.1\WindowsServiceDemo.exe"[SC] CreateService 成功

此时打开服务面板,便可以看到刚刚部署好的 WindowsServiceDemo 服务了。

到此,关于".NET Core开发Windows服务之怎么使用Quartz执行定时任务"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

服务 任务 方法 调度 实例 触发器 项目 容器 开发 成功 接口 时间 消息 配置 接下来 代码 学习 运行 就是 工厂 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州百单互联网科技有限公司 互联网科技公司的优势 互联网最新的科技 互联网电商科技 互联网科技会 互联网科技作文 奇酷互联网络科技公司 顺玮阁互联网科技 北京大学互联网科技怎么样 宁夏众和广鑫互联网科技有限公司 晓花互联网科技有限公司网址 阿大互联网科技有限公司 互联网新科技动漫ppt素材 互联网公司黑科技创始人 长沙渺峰互联网科技有限公司 杭州融税互联网科技有限公司 盐城市攀科互联网科技有限公司 河南商务圈互联网科技有限公司 互联网大会出现的黑科技 武汉亿视互联网科技有限公司 互联网 卓越科技 安徽鑫晟辉互联网科技 新浪科技互联网 狮子座互联网科技培训 智腾互联网科技有限公司 互联网新科技动漫ppt素材 群盈汇互联网科技有限公司 雨阳互联网卡科技有限公司 广州互联网高科技取餐柜 互联网企业和网络科技有限公司
0