使用 Quartz.NET 实现作业串行执行

Ø  前言

前两天,在公司的一个项目中编写 Windows 服务时,需求是当A服务运行完后,B服务才能运行,B服务运行后,C服务才能运行。因为B服务的数据依赖于A服务生成的数据,而C服务的数据又依赖于B服务。

在之前的文章中有介绍使用 Topshelf 结合 Quartz.NET 创建 Windows 服务,但是当时还不涉及这样的需求,经过后面看过一些相关博客后,便实现了该功能。另外,这里再写个 Demo 研究了一下。

 

Ø  假设我们有这样一个需求:

1.   就上一篇使用 Topshelf 结合 Quartz.NET 创建 Windows 服务而言,当我们更新商品库存后,我们需要发送短信和邮件通知管理员。

2.   而这两个动作都是两个独立的服务作业,并且它们都相互依赖。

3.   执行顺序:更新商品库存 -> 发送短信 -> 发送邮件,三者都是前一个服务执行完后,接着执行下个服务,下面是具体实现步骤。

 

1.   首先,我们定义服务配置文件quartz_jobs.xml

<!--该作业用于定时更新商品库存-->

<job>

  <name>UpdateInventoryJob</name>

  <group>JobGroup1</group>

  <description>定时更新商品库存</description>

  <job-type>TopshelfAndQuartz.UpdateInventoryJob,TopshelfAndQuartz</job-type>

  <durable>true</durable>

  <recover>false</recover>

</job>

<trigger>

  <cron>

    <name>UpdateInventoryTrigger</name>

    <group>UpdateInventoryTriggerGroup</group>

    <job-name>UpdateInventoryJob</job-name>

    <job-group>JobGroup1</job-group>

    <start-time>2017-12-01T00:00:00+08:00</start-time>

    <cron-expression>0 0/1 * * * ?</cron-expression>

  </cron>

</trigger>

<!--该作业用于发送短信-->

<job>

  <name>SendSMSJob</name>

  <group>JobGroup1</group>

  <description>发送短信作业</description>

  <job-type>TopshelfAndQuartz.SendSMSJob,TopshelfAndQuartz</job-type>

  <durable>true</durable>

  <recover>false</recover>

</job>

<trigger>

  <cron>

    <name>SendSMSJobTrigger</name>

    <group>SendSMSJobTriggerGroup</group>

    <job-name>SendSMSJob</job-name>

    <job-group>JobGroup1</job-group>

    <start-time>2027-12-01T00:00:00+08:00</start-time>

    <cron-expression>0 0/1 * * * ?</cron-expression>

  </cron>

</trigger>

<!--该作业用于发送邮件-->

<job>

  <name>SendMailJob</name>

  <group>JobGroup1</group>

  <description>发送邮件作业</description>

  <job-type>TopshelfAndQuartz.SendMailJob,TopshelfAndQuartz</job-type>

  <durable>true</durable>

  <recover>false</recover>

</job>

<trigger>

  <cron>

    <name>SendMailJobTrigger</name>

    <group>SendMailJobTriggerGroup</group>

    <job-name>SendMailJob</job-name>

    <job-group>JobGroup1</job-group>

    <start-time>2027-12-01T00:00:00+08:00</start-time>

    <cron-expression>0 0/1 * * * ?</cron-expression>

  </cron>

</trigger>

1)   可以发现,这里将作业分组名称都命名为“JobGroup1”,这是为了将这三个作业加入作业链中,需要将它们分为同一组中。

2)   另外,为了防止 SendSMSJobSendMailJob 在服务启动后自动执行,将<start-time>节点设置成了2027-12-01T00:00:00+08:00,因为不希望它们自动执行。

 

2.   定义发送短信、发送邮件作业(这里只是简单打印执行日志)

/// <summary>

/// 发送短信作业。

/// </summary>

public class SendSMSJob : IJob

{

    /// <summary>

    /// 作业被触发时执行该方法。

    /// </summary>

    public void Execute(IJobExecutionContext context)

    {

        Log.Logger.Info("开始执行发送短信作业");

    }

}

 

/// <summary>

/// 发送邮件作业。

/// </summary>

public class SendMailJob : IJob

{

    /// <summary>

    /// 作业被触发时执行该方法。

    /// </summary>

    public void Execute(IJobExecutionContext context)

    {

        Log.Logger.Info("开始执行发送邮件作业");

    }

}

 

3.   配置作业监听程序

/// <summary>

/// 配置作业监听。

/// </summary>

public static void ConfigureJobListener()

{

    ISchedulerFactory factory = new StdSchedulerFactory();

    IScheduler scheduler = factory.GetScheduler();

    JobChainingJobListener listener = null;

 

    //创建作业Key(名称与分组)

    JobKey uiJobKey = JobKey.Create("UpdateInventoryJob", "JobGroup1");

    JobKey sendSmsJobKey = JobKey.Create("SendSMSJob", "JobGroup1");

    JobKey sendMailJobKey = JobKey.Create("SendMailJob", "JobGroup1");

 

    //设置作业监听链

    listener = new JobChainingJobListener("链接更新库存、发送短信、发送邮件作业");

    listener.AddJobChainLink(uiJobKey, sendSmsJobKey);

    listener.AddJobChainLink(sendSmsJobKey, sendMailJobKey);

    scheduler.ListenerManager.AddJobListener(listener,

        GroupMatcher<JobKey>.GroupEquals("JobGroup1"));

}

 

4.   在服务运行前加入作业监听

Log.Logger.Info("服务开始运行");

ConfigureJobListener(); //配置作业监听

HostFactory.Run(o =>

{

    //o.UseLog4Net(); //这里需要使用 log4net, Version=1.2.15.0 的版本,当前版本不兼容所以注释掉

    o.Service<ServiceRunner>();

    o.SetServiceName("TopshelfAndQuartzService");

    o.SetDisplayName("库存更新服务");

    o.SetDescription("该服务用于定时更新商品库存");

    o.EnablePauseAndContinue();

});

 

5.   这样,我们作业监听链就配置好了,运行效果:

clip_image001[6]

 

Ø  总结

1.   其实 Quartz.NET 的功能还是很强大,它支持多个作业或触发设置监听,并可以自定义作业监听(实现 IJobListener 接口)或触发器监听(实现 ITriggerListener 接口),有兴趣的朋友可以深入研究。

2.   可参考文章:

1)   https://www.cnblogs.com/linzhao126/p/4528519.html

2)   http://www.cnblogs.com/zhangzhi19861216/p/4756610.html

3)   https://www.quartz-scheduler.net/documentation/index.html

转载于:https://www.cnblogs.com/abeam/p/8661274.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quartz.NET是一个开源的任务调度框架,它允许你轻松地在.NET应用程序中安排和执行定期任务(也称为cron作业)。V2.6版本提供了一些增强功能和改进,下面是使用Quartz.NET V2.6的一些关键步骤和注意事项: 1. 安装:首先,你需要从NuGet包管理器中安装Quartz.NET使用命令`Install-Package Quartz.Net`。 2. 设置:配置JobScheduler,通常会创建一个ISchedulerFactory实例并初始化Scheduler。在应用程序启动时,调用Scheduler的Start方法开始调度服务。 ```csharp using Quartz; //... var schedulerFactory = new StdSchedulerFactory(); IScheduler scheduler = schedulerFactory.GetScheduler(); scheduler.Start(); ``` 3. 创建Job:定义一个继承自IJob接口的类,并实现Execute方法,这是执行具体任务的地方。 ```csharp public class MyJob : IJob { public void Execute(IJobExecutionContext context) { // 你的业务逻辑 } } ``` 4. 定义Trigger:定义Job执行的时间规则,可以是固定时间、周期性、cron表达式等。 ```csharp ITrigger trigger = TriggerBuilder.Create() .WithSimpleSchedule(x => x.WithIntervalInMilliseconds(5000)) // 每5秒执行一次 .Build(); ``` 5. 安排执行:将Job和Trigger绑定到Scheduler上。 ```csharp scheduler.ScheduleJob(new JobDetail("myJob", "group1", typeof(MyJob)), trigger); ``` 6. 停止调度:在应用程序关闭时,记得停止Scheduler以确保所有任务都被正确处理。 ```csharp scheduler.Shutdown(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值