使用Quartz.NET在Winform中实现定时任务调度
背景
使用winform编写的运维服务器监控客户端自动启停任务经常报错,查看代码定时任务实现是通过Thread实现的。代码逻辑没有问题,执行一周之后出现会失效或者执行多次等等奇怪的问题。最后决定使用Quartz.NET来实现定时任务的问题。
具体步骤
1. 引入nuget包
Quartz
2.代码编写
1.实现IJob接口的作业类
public class UpdateUIJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
if (Application.OpenForms != null && Application.OpenForms != null && Application.OpenForms.Count != 0)
{
foreach (Form form in Application.OpenForms)
{
//根据名称找到 当前页面
if (form.Name == "MainForm")
{
//执行任务
((MainForm)form).Invoke(new Action(() =>
{ ((MainForm)form).richTextBox.AppendText("Updated at " + DateTime.Now + Environment.NewLine); }));
}
}
}
}
2.实现自定义作业工厂
public class MyJobFactory : IJobFactory
{
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return new UpdateUIJob();
}
public void ReturnJob(IJob job)
{
// 可选实现
}
}
3.触发方法
private void InitializeScheduler()
{
// 创建调度器工厂
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
// 获取调度器
scheduler = schedulerFactory.GetScheduler().Result;
scheduler.JobFactory = new MyJobFactory(); // 使用自定义作业工厂
// 启动调度器
scheduler.Start();
// 定义作业详细信息
IJobDetail job = JobBuilder.Create<UpdateUIJob>()
.WithIdentity("updateUIJob", "group1")
.Build();
// 定义触发器,每10秒触发一次
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("updateUITrigger", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.RepeatForever())
.Build();
// 将作业和触发器添加到调度器
scheduler.ScheduleJob(job, trigger);
}
#全部代码
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsApp1
{
// 定义你的WinForms窗体
public partial class MainForm : Form
{
private IScheduler scheduler;
private RichTextBox richTextBox;
public MainForm()
{
InitializeComponent();
richTextBox = new RichTextBox();
this.Controls.Add(richTextBox);
richTextBox.Dock = DockStyle.Fill;
InitializeScheduler();
}
/// <summary>
/// 3.触发方法
/// </summary>
private void InitializeScheduler()
{
// 创建调度器工厂
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
// 获取调度器
scheduler = schedulerFactory.GetScheduler().Result;
scheduler.JobFactory = new MyJobFactory(); // 使用自定义作业工厂
// 启动调度器
scheduler.Start();
// 定义作业详细信息
IJobDetail job = JobBuilder.Create<UpdateUIJob>()
.WithIdentity("updateUIJob", "group1")
.Build();
// 定义触发器,每10秒触发一次
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("updateUITrigger", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.RepeatForever())
.Build();
// 将作业和触发器添加到调度器
scheduler.ScheduleJob(job, trigger);
}
// 2.实现自定义作业工厂
public class MyJobFactory : IJobFactory
{
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
return new UpdateUIJob();
}
public void ReturnJob(IJob job)
{
// 可选实现
}
}
// 1.实现IJob接口的作业类
public class UpdateUIJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
if (Application.OpenForms != null && Application.OpenForms != null && Application.OpenForms.Count != 0)
{
foreach (Form form in Application.OpenForms)
{
//根据名称找到 当前页面
if (form.Name == "MainForm")
{
//执行任务
((MainForm)form).Invoke(new Action(() =>
{ ((MainForm)form).richTextBox.AppendText("Updated at " + DateTime.Now + Environment.NewLine); }));
}
}
}
}
}
}
}
#调用多个
using Quartz;
using Quartz.Impl;
public class Program
{
public static async Task Main(string[] args)
{
// 1. 创建Scheduler
IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
// 2. 开启Scheduler
await scheduler.Start();
// 3. 定义Job和Trigger
IJobDetail job1 = JobBuilder.Create<MyJob>()
.WithIdentity("job1", "group1")
.Build();
ITrigger trigger1 = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever())
.Build();
IJobDetail job2 = JobBuilder.Create<AnotherJob>()
.WithIdentity("job2", "group2")
.Build();
ITrigger trigger2 = TriggerBuilder.Create()
.WithIdentity("trigger2", "group2")
.StartNow()
.WithSimpleSchedule(x => x.WithIntervalInSeconds(20).RepeatForever())
.Build();
// 4. 将Job和Trigger添加到Scheduler
await scheduler.ScheduleJob(job1, trigger1);
await scheduler.ScheduleJob(job2, trigger2);
}
}
// 你的第一个Job
public class MyJob : IJob
{
public Task Execute(IJobExecutionContext context)
{
// 你的任务逻辑
Console.WriteLine("MyJob is running.");
return Task.CompletedTask;
}
}
// 你的第二个Job
public class AnotherJob : IJob
{
public Task Execute(IJobExecutionContext context)
{
// 你的任务逻辑
Console.WriteLine("AnotherJob is running.");
return Task.CompletedTask;
}
}
工作中善于使用现有轮子也很重要,解决方法千千万,不要钻牛角尖。
毕竟老板只看结果。