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

在实际的项目中,常遇到延时触发工作以及定时触发工作

这里所讲的是借助第三方的组件 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;
        }
    }
}
原文地址:https://www.cnblogs.com/terryK/p/11686134.html