C# 定时任务
C# 定时任务| Id | Title | DateAdded | SourceUrl | PostType | Body | BlogId | Description | DateUpdated | IsMarkdown | EntryName | CreatedTime | IsActive | AutoDesc | AccessPermission |
| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------|
| 17165281| C# 定时任务| 2023-02-28T17:26:00| | BlogPost|
C# 定时任务 - XL、 - 博客园 (cnblogs.com)
工作中需要做个每天定时发邮件的功能,了解之后知道java里有做定时任务比较容易的方法,就是Quartz,在C#里叫Quartz.Net。
在写代码之前需要引用几个dll文件,分别是C5.dll、Common.Logging.dll和Quartz.dll;还有一个QuartzManager.cs文件,直接复制到项目中
QuartzManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
namespace Quartz
{
public static class QuartzManager
{
private static ISchedulerFactory sf = null;
private static IScheduler sched = null;
</span><span style="color: #0000ff;">static</span><span style="color: #000000;"> QuartzManager()
{
sf </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> StdSchedulerFactory();
sched </span>=<span style="color: #000000;"> sf.GetScheduler();
sched.Start();
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 添加Job 并且以定点的形式运行
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><typeparam name="T"></typeparam></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="CronTime"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="jobDataMap"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> DateTimeOffset AddJob<T>(<span style="color: #0000ff;">string</span> JobName, <span style="color: #0000ff;">string</span> CronTime, <span style="color: #0000ff;">string</span> jobData) <span style="color: #0000ff;">where</span><span style="color: #000000;"> T : IJob
{
IJobDetail jobCheck </span>= JobBuilder.Create<T>().WithIdentity(JobName, JobName + <span style="color: #800000;">"</span><span style="color: #800000;">_Group</span><span style="color: #800000;">"</span>).UsingJobData(<span style="color: #800000;">"</span><span style="color: #800000;">jobData</span><span style="color: #800000;">"</span><span style="color: #000000;">, jobData).Build();
ICronTrigger CronTrigger </span>= <span style="color: #0000ff;">new</span> CronTriggerImpl(JobName + <span style="color: #800000;">"</span><span style="color: #800000;">_CronTrigger</span><span style="color: #800000;">"</span>, JobName + <span style="color: #800000;">"</span><span style="color: #800000;">_TriggerGroup</span><span style="color: #800000;">"</span><span style="color: #000000;">, CronTime);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> sched.ScheduleJob(jobCheck, CronTrigger);
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 添加Job 并且以定点的形式运行
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><typeparam name="T"></typeparam></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="CronTime"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> DateTimeOffset AddJob<T>(<span style="color: #0000ff;">string</span> JobName, <span style="color: #0000ff;">string</span> CronTime) <span style="color: #0000ff;">where</span><span style="color: #000000;"> T : IJob
{
</span><span style="color: #0000ff;">return</span> AddJob<T>(JobName, CronTime, <span style="color: #0000ff;">null</span><span style="color: #000000;">);
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 添加Job 并且以周期的形式运行
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><typeparam name="T"></typeparam></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="SimpleTime"></span><span style="color: #008000;">毫秒数</span><span style="color: #808080;"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> DateTimeOffset AddJob<T>(<span style="color: #0000ff;">string</span> JobName, <span style="color: #0000ff;">int</span> SimpleTime) <span style="color: #0000ff;">where</span><span style="color: #000000;"> T : IJob
{
</span><span style="color: #0000ff;">return</span> AddJob<T>(JobName, DateTime.UtcNow.AddMilliseconds(<span style="color: #800080;">1</span><span style="color: #000000;">), TimeSpan.FromMilliseconds(SimpleTime));
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 添加Job 并且以周期的形式运行
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><typeparam name="T"></typeparam></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="SimpleTime"></span><span style="color: #008000;">毫秒数</span><span style="color: #808080;"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> DateTimeOffset AddJob<T>(<span style="color: #0000ff;">string</span> JobName, DateTimeOffset StartTime, <span style="color: #0000ff;">int</span> SimpleTime) <span style="color: #0000ff;">where</span><span style="color: #000000;"> T : IJob
{
</span><span style="color: #0000ff;">return</span> AddJob<T><span style="color: #000000;">(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime));
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 添加Job 并且以周期的形式运行
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><typeparam name="T"></typeparam></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="SimpleTime"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> DateTimeOffset AddJob<T>(<span style="color: #0000ff;">string</span> JobName, DateTimeOffset StartTime, TimeSpan SimpleTime) <span style="color: #0000ff;">where</span><span style="color: #000000;"> T : IJob
{
</span><span style="color: #0000ff;">return</span> AddJob<T>(JobName, StartTime, SimpleTime, <span style="color: #0000ff;">new</span> Dictionary<<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">object</span>><span style="color: #000000;">());
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 添加Job 并且以周期的形式运行
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><typeparam name="T"></typeparam></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="StartTime"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="SimpleTime"></span><span style="color: #008000;">毫秒数</span><span style="color: #808080;"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="jobDataMap"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> DateTimeOffset AddJob<T>(<span style="color: #0000ff;">string</span> JobName, DateTimeOffset StartTime, <span style="color: #0000ff;">int</span> SimpleTime, <span style="color: #0000ff;">string</span> MapKey, <span style="color: #0000ff;">object</span> MapValue) <span style="color: #0000ff;">where</span><span style="color: #000000;"> T : IJob
{
Dictionary</span><<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">object</span>> map = <span style="color: #0000ff;">new</span> Dictionary<<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">object</span>><span style="color: #000000;">();
map.Add(MapKey, MapValue);
</span><span style="color: #0000ff;">return</span> AddJob<T><span style="color: #000000;">(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime), map);
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 添加Job 并且以周期的形式运行
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><typeparam name="T"></typeparam></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="StartTime"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="SimpleTime"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="jobDataMap"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><returns></returns></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> DateTimeOffset AddJob<T>(<span style="color: #0000ff;">string</span> JobName, DateTimeOffset StartTime, TimeSpan SimpleTime, Dictionary<<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">object</span>> map) <span style="color: #0000ff;">where</span><span style="color: #000000;"> T : IJob
{
IJobDetail jobCheck </span>= JobBuilder.Create<T>().WithIdentity(JobName, JobName + <span style="color: #800000;">"</span><span style="color: #800000;">_Group</span><span style="color: #800000;">"</span><span style="color: #000000;">).Build();
jobCheck.JobDataMap.PutAll(map);
ISimpleTrigger triggerCheck </span>= <span style="color: #0000ff;">new</span> SimpleTriggerImpl(JobName + <span style="color: #800000;">"</span><span style="color: #800000;">_SimpleTrigger</span><span style="color: #800000;">"</span>, JobName + <span style="color: #800000;">"</span><span style="color: #800000;">_TriggerGroup</span><span style="color: #800000;">"</span><span style="color: #000000;">,
StartTime,
</span><span style="color: #0000ff;">null</span><span style="color: #000000;">,
SimpleTriggerImpl.RepeatIndefinitely,
SimpleTime);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> sched.ScheduleJob(jobCheck, triggerCheck);
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 修改触发器时间,需要job名,以及修改结果
</span><span style="color: #808080;">///</span><span style="color: #008000;"> CronTriggerImpl类型触发器
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> UpdateTime(<span style="color: #0000ff;">string</span> jobName, <span style="color: #0000ff;">string</span><span style="color: #000000;"> CronTime)
{
TriggerKey TKey </span>= <span style="color: #0000ff;">new</span> TriggerKey(jobName + <span style="color: #800000;">"</span><span style="color: #800000;">_CronTrigger</span><span style="color: #800000;">"</span>, jobName + <span style="color: #800000;">"</span><span style="color: #800000;">_TriggerGroup</span><span style="color: #800000;">"</span><span style="color: #000000;">);
CronTriggerImpl cti </span>= sched.GetTrigger(TKey) <span style="color: #0000ff;">as</span><span style="color: #000000;"> CronTriggerImpl;
cti.CronExpression </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> CronExpression(CronTime);
sched.RescheduleJob(TKey, cti);
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 修改触发器时间,需要job名,以及修改结果
</span><span style="color: #808080;">///</span><span style="color: #008000;"> SimpleTriggerImpl类型触发器
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="jobName"></param></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="SimpleTime"></span><span style="color: #008000;">分钟数</span><span style="color: #808080;"></param></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> UpdateTime(<span style="color: #0000ff;">string</span> jobName, <span style="color: #0000ff;">int</span><span style="color: #000000;"> SimpleTime)
{
UpdateTime(jobName, TimeSpan.FromMinutes(SimpleTime));
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 修改触发器时间,需要job名,以及修改结果
</span><span style="color: #808080;">///</span><span style="color: #008000;"> SimpleTriggerImpl类型触发器
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> UpdateTime(<span style="color: #0000ff;">string</span><span style="color: #000000;"> jobName, TimeSpan SimpleTime)
{
TriggerKey TKey </span>= <span style="color: #0000ff;">new</span> TriggerKey(jobName + <span style="color: #800000;">"</span><span style="color: #800000;">_SimpleTrigger</span><span style="color: #800000;">"</span>, jobName + <span style="color: #800000;">"</span><span style="color: #800000;">_TriggerGroup</span><span style="color: #800000;">"</span><span style="color: #000000;">);
SimpleTriggerImpl sti </span>= sched.GetTrigger(TKey) <span style="color: #0000ff;">as</span><span style="color: #000000;"> SimpleTriggerImpl;
sti.RepeatInterval </span>=<span style="color: #000000;"> SimpleTime;
sched.RescheduleJob(TKey, sti);
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 暂停所有Job
</span><span style="color: #808080;">///</span><span style="color: #008000;"> 暂停功能Quartz提供有很多,以后可扩充
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> PauseAll()
{
sched.PauseAll();
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 恢复所有Job
</span><span style="color: #808080;">///</span><span style="color: #008000;"> 恢复功能Quartz提供有很多,以后可扩充
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> ResumeAll()
{
sched.ResumeAll();
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 删除Job
</span><span style="color: #808080;">///</span><span style="color: #008000;"> 删除功能Quartz提供有很多,以后可扩充
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="JobName"></param></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> DeleteJob(<span style="color: #0000ff;">string</span><span style="color: #000000;"> JobName)
{
JobKey jk </span>= <span style="color: #0000ff;">new</span> JobKey(JobName, JobName + <span style="color: #800000;">"</span><span style="color: #800000;">_Group</span><span style="color: #800000;">"</span><span style="color: #000000;">);
sched.DeleteJob(jk);
}
</span><span style="color: #808080;">///</span> <span style="color: #808080;"><summary></span>
<span style="color: #808080;">///</span><span style="color: #008000;"> 卸载定时器
</span><span style="color: #808080;">///</span> <span style="color: #808080;"></summary></span>
<span style="color: #808080;">///</span> <span style="color: #808080;"><param name="waitForJobsToComplete"></span><span style="color: #008000;">是否等待job执行完成</span><span style="color: #808080;"></param></span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Shutdown(<span style="color: #0000ff;">bool</span><span style="color: #000000;"> waitForJobsToComplete)
{
sched.Shutdown(waitForJobsToComplete);
}
}
}
窗体界面上只有一个Button按钮,点击之后将当前Windows窗体关闭,而我的定时任务就是实现这个关闭。
.closeForm();关闭窗体方法在另写的一个stopjob.cs类文件调用 这个类需要继承IJob
using Quartz; using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace winform状态栏
{
[PersistJobDataAfterExecution]
[DisallowConcurrentExecution]
public class stopjob : IJob
{
public void Execute(IJobExecutionContext context)
{
Program.form.closeForm();
}
}
}
上面代码中,Program.form并不是开始创建的那个窗体,而是在Program类文件中创建的静态Form。为什么另创建一个静态Form?涉及到子线程关闭主线程问题
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace winform状态栏
{
static class Program
{
public static Form1 form;
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form1();
Application.Run(form);
}
}
}
Form.cs文件里引用Quartz(using Quartz;)
然后是关闭按钮(Button)的事件
using Quartz;
using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace winform状态栏
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button_close(object sender, EventArgs e)
{
//cron表达式 参考 http://www.cnblogs.com/sunjie9606/archive/2012/03/15/2397626.html
QuartzManager.AddJob<stopjob>("每隔5秒", "*/5 * * * * ?");//每隔5秒执行一次这个方法
}
private delegate void CloseForm();//设计到多线程,子线程去控制主线程的控件,InvokeRequired值为true,用到定义委托,使得这个控制行为成为主线程的行为
public void closeForm()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new CloseForm(closeForm));
}
else
{
this.Close();
}
}
}
}
关于执行stopjob的时间,我这里是用的每隔5秒执行一次,具体的解释在另一位博主那里有介绍
http://www.cnblogs.com/sunjie9606/archive/2012/03/15/2397626.html
其中C5.dll、Common.Logging.dll、Quartz.dll文件的链接http://pan.baidu.com/s/1hsBn1Bm(如果失效联系博主)
我学习Quartz.Net时用的是winform,大家可以试试别的,这样关于线程的问题应该就可以避免,这也是我没有想到的问题
| 648658| | 2024-04-29T20:51:00| false| | 2023-02-28T17:25:55.4| true| C# 定时任务 - XL、 - 博客园 (cnblogs.com) 工作中需要做个每天定时发邮件的功能,了解之后知道java里有做定时任务比较容易的方法,就是Quartz,在C#里叫Quartz.Net。 在写代码之前需要引用几个dll文件,分别是C5.dll、Common.Logging.dll和| Anonymous|
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现