• 三分钟掌握,使用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;
            }
        }
    }
  • 相关阅读:
    一本名副其实的 Web架构“圣经”——关于《HTTP权威指南》
    图灵生日会——纪念阿兰图灵诞辰100周年及图灵公司七周年线下交流会
    跟着图灵听课去!(六月)
    “电梯演讲”最精炼、贴切的语言
    送你一把开启演讲之路的钥匙——《演讲的艺术》
    翻译是一份严谨的工作——关于HTTP中文翻译的讨论
    浪潮之巅作者吴军推荐序——《推荐系统实践》
    如何到达永生?揭示科学之美
    软件行业大牛告诉你何谓成功?
    C#线程系列讲座(3):线程池和文件下载服务器
  • 原文地址:https://www.cnblogs.com/terryK/p/11686134.html
Copyright © 2020-2023  润新知