欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

三分钟掌握,使用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

三分钟掌握,使用Quqrtz.Net实现定时发送邮件

 

 

 

三分钟掌握,使用Quqrtz.Net实现定时发送邮件

 

 

 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;
        }
    }
}