三分钟掌握,使用Quqrtz.Net实现定时发送邮件
程序员文章站
2023-11-13 13:12:28
使用Quqrtz.Net实现定时发送邮件,注意邮箱要开通Smtp服务 ......
在实际的项目中,常遇到延时触发工作以及定时触发工作
这里所讲的是借助第三方的组件 quartz.net 来实现(源码位置:https://github.com/quartznet/quartznet)
实现思路(来自博友wuzh)
一:继承并实现ijob接口,在execute 方法中写你要定时执行的事情(切记 )
二:使用quartz创建任务调度核心代码步骤
1、配置quartz,创建工厂,开启调度。
2、创建工作任务
3、创建触发器
4、将任务加入到任务池
demo 创建控制台应用程序,定时发送邮件以及延时写日志
1 在vs2015中使用nuget,获取quartz
2 创建两个作业
/// <summary> /// 继承并实现ijob接口,在execute 方法中写你要定时执行的事情(切记 ) /// </summary> public class myjob : ijob { public task execute(ijobexecutioncontext context) { task task = null; try { string filename = "printlog.txt"; using (streamwriter writer = new streamwriter(filename, true)) { task = writer.writelineasync(string.format("{0},测试", datetime.now.tolongtimestring())); console.writeline(string.format("{0},测试", datetime.now.tolongtimestring())); } } catch (exception) { } return task.completedtask; } } /// <summary> /// 发邮件 /// </summary> public class sendemailjob : ijob { public task execute(ijobexecutioncontext context) { //smtp sendemail.sendmailusegmail("49564753x@qq.com", "49564753x@qq.com", "terryk", "quartz.net定时作业", "quartz.net定时发送邮件", "tiyklkinqanxbgxx", 587, "smtp.qq.com", true); return task.completedtask; } } public class sendemail { public static task sendmailusegmail(string touseraddress, string fromuseraddress, string fromusername, string contextname, string context, string fromuserpass, int port, string host, bool sslstate) { using (mailmessage mailmessage = new mailmessage()) { mailmessage.to.add(touseraddress); mailmessage.from = new mailaddress(fromuseraddress, fromusername, encoding.utf8); mailmessage.subject = contextname; mailmessage.subjectencoding = encoding.utf8; mailmessage.body = context; mailmessage.bodyencoding = encoding.utf8; mailmessage.isbodyhtml = false; mailmessage.priority = mailpriority.high; smtpclient smtpclient = new smtpclient(); smtpclient.credentials = new networkcredential(fromuseraddress, fromuserpass); smtpclient.port = port; smtpclient.host = host; smtpclient.enablessl = sslstate; try { smtpclient.send(mailmessage); console.writeline("发送成功,请查看"); } catch (smtpexception var_3_a8) { console.writeline(var_3_a8.tostring()); } } return task.completedtask; } }
3 创建quartzhelper,用于配置环境以及完成 ischeduler, ijobdetails 与 itrigger之间的配置
public class quartzhelper { static readonly ischeduler _scheduler; static quartzhelper() { #region 配置 quartz namevaluecollection properties = new namevaluecollection { {"quartz.serializer.type","binary"} }; // 设置线程池 properties["quartz.threadpool.type"] = "quartz.simpl.simplethreadpool, quartz"; //设置线程池的最大线程数量 properties["quartz.threadpool.threadcount"] = "10"; //设置作业中每个线程的优先级 properties["quartz.threadpool.threadpriority"] = threadpriority.normal.tostring(); // 远程输出配置 properties["quartz.scheduler.exporter.type"] = "quartz.simpl.remotingschedulerexporter, quartz"; properties["quartz.scheduler.exporter.port"] = "555"; //配置端口号 properties["quartz.scheduler.exporter.bindname"] = "quartzscheduler"; properties["quartz.scheduler.exporter.channeltype"] = "tcp"; //协议类型 #endregion //创建一个工厂 var schedulerfactory = new stdschedulerfactory(properties); //启动 _scheduler = schedulerfactory.getscheduler().result; //1、开启调度 _scheduler.start(); } /// <summary> /// 时间间隔执行任务 /// </summary> /// <typeparam name="t">任务类,必须实现ijob接口</typeparam> /// <param name="seconds">时间间隔(单位:秒)</param> public static async task asyncexecuteinterval<t>(int seconds) where t : ijob { //2、创建工作任务 ijobdetail job = jobbuilder.create<t>() .withidentity("printlog", "loggroup") .build(); // 3、创建触发器 itrigger trigger = triggerbuilder.create() .startnow() .withidentity("logtrigger", "loggroup") .withsimpleschedule(x => x.withintervalinseconds(seconds).repeatforever()) .build(); //4、将任务加入到任务池 await _scheduler.schedulejob(job, trigger); } /// <summary> /// 指定时间执行任务 /// </summary> /// <typeparam name="t">任务类,必须实现ijob接口</typeparam> /// <param name="cronexpression">cron表达式,即指定时间点的表达式</param> public static async task<bool> asyncexecutebycron<t>(string cronexpression) where t : ijob { //2、创建工作任务 ijobdetail job = jobbuilder.create<t>() .withidentity("sendemailjob", "emailgroup") .build(); //3、创建触发器 icrontrigger trigger = (icrontrigger)triggerbuilder.create() .startnow() .withidentity("sendemail", "emailgroup") .withcronschedule(cronexpression) .build(); //4、将任务加入到任务池 await _scheduler.schedulejob(job, trigger); return true; } }
4 运行调用
public class program { static void main(string[] args) { task.run(() => { string cronexpression = "0 36 15,20 ? * mon-fri"; // =>周一到周五 每天上午8:30以及下午8:30执行定时任务(发送邮件) quartzhelper.asyncexecutebycron<sendemailjob>(cronexpression).wait(); });//=>这是调用cron计划方法 task.run(() => quartzhelper.asyncexecuteinterval<myjob>(5).wait()); /* 简单说一下cron表达式: 由7段构成:秒 分 时 日 月 星期 年(可选) "-" :表示范围 mon-wed表示星期一到星期三 "," :表示列举 mon,web表示星期一和星期三 "*" :表是“每”,每月,每天,每周,每年等 "/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始 "?" :只能出现在日,星期段里面,表示不指定具体的值 "l" :只能出现在日,星期段里面,是last的缩写,一个月的最后一天,一个星期的最后一天(星期六) "w" :表示工作日,距离给定值最近的工作日 "#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=sun...6=fri,7=sat) 如果minutes的数值是 '0/15' ,表示从0开始每15分钟执行 如果minutes的数值是 '3/20' ,表示从3开始每20分钟执行,也就是‘3/23/43’ */ console.readkey(); } }
5 整个demo代码
using quartz; using quartz.impl; using system; using system.collections.generic; using system.collections.specialized; using system.io; using system.linq; using system.net; using system.net.mail; using system.text; using system.threading; using system.threading.tasks; namespace quartz { public class program { static void main(string[] args) { task.run(() => { string cronexpression = "0 30 8,20 ? * mon-fri"; // =>周一到周五 每天上午8:30以及下午8:30执行定时任务(发送邮件) quartzhelper.asyncexecutebycron<sendemailjob>(cronexpression).wait(); });//=>这是调用cron计划方法 task.run(() => quartzhelper.asyncexecuteinterval<myjob>(5).wait()); /* 简单说一下cron表达式: 由7段构成:秒 分 时 日 月 星期 年(可选) "-" :表示范围 mon-wed表示星期一到星期三 "," :表示列举 mon,web表示星期一和星期三 "*" :表是“每”,每月,每天,每周,每年等 "/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始 "?" :只能出现在日,星期段里面,表示不指定具体的值 "l" :只能出现在日,星期段里面,是last的缩写,一个月的最后一天,一个星期的最后一天(星期六) "w" :表示工作日,距离给定值最近的工作日 "#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=sun...6=fri,7=sat) 如果minutes的数值是 '0/15' ,表示从0开始每15分钟执行 如果minutes的数值是 '3/20' ,表示从3开始每20分钟执行,也就是‘3/23/43’ */ console.readkey(); } } /// <summary> /// 继承并实现ijob接口,在execute 方法中写你要定时执行的事情(切记 ) /// </summary> public class myjob : ijob { public task execute(ijobexecutioncontext context) { task task = null; try { string filename = "printlog.txt"; using (streamwriter writer = new streamwriter(filename, true)) { task = writer.writelineasync(string.format("{0},测试", datetime.now.tolongtimestring())); console.writeline(string.format("{0},测试", datetime.now.tolongtimestring())); } } catch (exception) { } return task.completedtask; } } /// <summary> /// 发邮件 /// </summary> public class sendemailjob : ijob { public task execute(ijobexecutioncontext context) { //smtp sendemail.sendmailusegmail("49564753x@qq.com", "49564753x@qq.com", "terryk", "quartz.net定时作业", "quartz.net定时发送邮件", "tiyklkinqanxbgxx", 587, "smtp.qq.com", true); return task.completedtask; } } public class sendemail { public static task sendmailusegmail(string touseraddress, string fromuseraddress, string fromusername, string contextname, string context, string fromuserpass, int port, string host, bool sslstate) { using (mailmessage mailmessage = new mailmessage()) { mailmessage.to.add(touseraddress); mailmessage.from = new mailaddress(fromuseraddress, fromusername, encoding.utf8); mailmessage.subject = contextname; mailmessage.subjectencoding = encoding.utf8; mailmessage.body = context; mailmessage.bodyencoding = encoding.utf8; mailmessage.isbodyhtml = false; mailmessage.priority = mailpriority.high; smtpclient smtpclient = new smtpclient(); smtpclient.credentials = new networkcredential(fromuseraddress, fromuserpass); smtpclient.port = port; smtpclient.host = host; smtpclient.enablessl = sslstate; try { smtpclient.send(mailmessage); console.writeline("发送成功,请查看"); } catch (smtpexception var_3_a8) { console.writeline(var_3_a8.tostring()); } } return task.completedtask; } } public class quartzhelper { static readonly ischeduler _scheduler; static quartzhelper() { #region 配置 quartz namevaluecollection properties = new namevaluecollection { {"quartz.serializer.type","binary"} }; // 设置线程池 properties["quartz.threadpool.type"] = "quartz.simpl.simplethreadpool, quartz"; //设置线程池的最大线程数量 properties["quartz.threadpool.threadcount"] = "10"; //设置作业中每个线程的优先级 properties["quartz.threadpool.threadpriority"] = threadpriority.normal.tostring(); // 远程输出配置 properties["quartz.scheduler.exporter.type"] = "quartz.simpl.remotingschedulerexporter, quartz"; properties["quartz.scheduler.exporter.port"] = "555"; //配置端口号 properties["quartz.scheduler.exporter.bindname"] = "quartzscheduler"; properties["quartz.scheduler.exporter.channeltype"] = "tcp"; //协议类型 #endregion //创建一个工厂 var schedulerfactory = new stdschedulerfactory(properties); //启动 _scheduler = schedulerfactory.getscheduler().result; //1、开启调度 _scheduler.start(); } /// <summary> /// 时间间隔执行任务 /// </summary> /// <typeparam name="t">任务类,必须实现ijob接口</typeparam> /// <param name="seconds">时间间隔(单位:秒)</param> public static async task asyncexecuteinterval<t>(int seconds) where t : ijob { //2、创建工作任务 ijobdetail job = jobbuilder.create<t>() .withidentity("printlog", "loggroup") .build(); // 3、创建触发器 itrigger trigger = triggerbuilder.create() .startnow() .withidentity("logtrigger", "loggroup") .withsimpleschedule(x => x.withintervalinseconds(seconds).repeatforever()) .build(); //4、将任务加入到任务池 await _scheduler.schedulejob(job, trigger); } /// <summary> /// 指定时间执行任务 /// </summary> /// <typeparam name="t">任务类,必须实现ijob接口</typeparam> /// <param name="cronexpression">cron表达式,即指定时间点的表达式</param> public static async task<bool> asyncexecutebycron<t>(string cronexpression) where t : ijob { //2、创建工作任务 ijobdetail job = jobbuilder.create<t>() .withidentity("sendemailjob", "emailgroup") .build(); //3、创建触发器 icrontrigger trigger = (icrontrigger)triggerbuilder.create() .startnow() .withidentity("sendemail", "emailgroup") .withcronschedule(cronexpression) .build(); //4、将任务加入到任务池 await _scheduler.schedulejob(job, trigger); return true; } } }