zoukankan      html  css  js  c++  java
  • C# 定时任务

    工作中需要做个每天定时发邮件的功能,了解之后知道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;
    
            static QuartzManager()
            {
                sf = new StdSchedulerFactory();
                sched = sf.GetScheduler();
                sched.Start();
            }
    
            /// <summary>
            /// 添加Job 并且以定点的形式运行
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="JobName"></param>
            /// <param name="CronTime"></param>
            /// <param name="jobDataMap"></param>
            /// <returns></returns>
            public static DateTimeOffset AddJob<T>(string JobName, string CronTime, string jobData) where T : IJob
            {
                IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").UsingJobData("jobData", jobData).Build();
                ICronTrigger CronTrigger = new CronTriggerImpl(JobName + "_CronTrigger", JobName + "_TriggerGroup", CronTime);
                return sched.ScheduleJob(jobCheck, CronTrigger);
            }
    
            /// <summary>
            /// 添加Job 并且以定点的形式运行
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="JobName"></param>
            /// <param name="CronTime"></param>
            /// <returns></returns>
            public static DateTimeOffset AddJob<T>(string JobName, string CronTime) where T : IJob
            {
                return AddJob<T>(JobName, CronTime, null);
            }
    
            /// <summary>
            /// 添加Job 并且以周期的形式运行
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="JobName"></param>
            /// <param name="SimpleTime">毫秒数</param>
            /// <returns></returns>
            public static DateTimeOffset AddJob<T>(string JobName, int SimpleTime) where T : IJob
            {
                return AddJob<T>(JobName, DateTime.UtcNow.AddMilliseconds(1), TimeSpan.FromMilliseconds(SimpleTime));
            }
    
            /// <summary>
            /// 添加Job 并且以周期的形式运行
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="JobName"></param>
            /// <param name="SimpleTime">毫秒数</param>
            /// <returns></returns>
            public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime) where T : IJob
            {
                return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime));
            }
    
            /// <summary>
            /// 添加Job 并且以周期的形式运行
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="JobName"></param>
            /// <param name="SimpleTime"></param>
            /// <returns></returns>
            public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime) where T : IJob
            {
                return AddJob<T>(JobName, StartTime, SimpleTime, new Dictionary<string, object>());
            }
    
            /// <summary>
            /// 添加Job 并且以周期的形式运行
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="JobName"></param>
            /// <param name="StartTime"></param>
            /// <param name="SimpleTime">毫秒数</param>
            /// <param name="jobDataMap"></param>
            /// <returns></returns>
            public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime, string MapKey, object MapValue) where T : IJob
            {
                Dictionary<string, object> map = new Dictionary<string, object>();
                map.Add(MapKey, MapValue);
                return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime), map);
            }
    
            /// <summary>
            /// 添加Job 并且以周期的形式运行
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="JobName"></param>
            /// <param name="StartTime"></param>
            /// <param name="SimpleTime"></param>
            /// <param name="jobDataMap"></param>
            /// <returns></returns>
            public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime, Dictionary<string, object> map) where T : IJob
            {
                IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").Build();
                jobCheck.JobDataMap.PutAll(map);
                ISimpleTrigger triggerCheck = new SimpleTriggerImpl(JobName + "_SimpleTrigger", JobName + "_TriggerGroup",
                                            StartTime,
                                            null,
                                            SimpleTriggerImpl.RepeatIndefinitely,
                                            SimpleTime);
                return sched.ScheduleJob(jobCheck, triggerCheck);
            }
    
            /// <summary>
            /// 修改触发器时间,需要job名,以及修改结果
            /// CronTriggerImpl类型触发器
            /// </summary>
            public static void UpdateTime(string jobName, string CronTime)
            {
                TriggerKey TKey = new TriggerKey(jobName + "_CronTrigger", jobName + "_TriggerGroup");
                CronTriggerImpl cti = sched.GetTrigger(TKey) as CronTriggerImpl;
                cti.CronExpression = new CronExpression(CronTime);
                sched.RescheduleJob(TKey, cti);
            }
    
            /// <summary>
            /// 修改触发器时间,需要job名,以及修改结果
            /// SimpleTriggerImpl类型触发器
            /// </summary>
            /// <param name="jobName"></param>
            /// <param name="SimpleTime">分钟数</param>
            public static void UpdateTime(string jobName, int SimpleTime)
            {
                UpdateTime(jobName, TimeSpan.FromMinutes(SimpleTime));
            }
    
            /// <summary>
            /// 修改触发器时间,需要job名,以及修改结果
            /// SimpleTriggerImpl类型触发器
            /// </summary>
            public static void UpdateTime(string jobName, TimeSpan SimpleTime)
            {
                TriggerKey TKey = new TriggerKey(jobName + "_SimpleTrigger", jobName + "_TriggerGroup");
                SimpleTriggerImpl sti = sched.GetTrigger(TKey) as SimpleTriggerImpl;
                sti.RepeatInterval = SimpleTime;
                sched.RescheduleJob(TKey, sti);
            }
    
            /// <summary>
            /// 暂停所有Job
            /// 暂停功能Quartz提供有很多,以后可扩充
            /// </summary>
            public static void PauseAll()
            {
                sched.PauseAll();
            }
    
            /// <summary>
            /// 恢复所有Job
            /// 恢复功能Quartz提供有很多,以后可扩充
            /// </summary>
            public static void ResumeAll()
            {
                sched.ResumeAll();
            }
    
            /// <summary>
            /// 删除Job
            /// 删除功能Quartz提供有很多,以后可扩充
            /// </summary>
            /// <param name="JobName"></param>
            public static void DeleteJob(string JobName)
            {
                JobKey jk = new JobKey(JobName, JobName + "_Group");
                sched.DeleteJob(jk);
            }
    
            /// <summary>
            /// 卸载定时器
            /// </summary>
            /// <param name="waitForJobsToComplete">是否等待job执行完成</param>
            public static void Shutdown(bool 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,大家可以试试别的,这样关于线程的问题应该就可以避免,这也是我没有想到的问题

  • 相关阅读:
    面试汇总
    Windows 环境下的 protoc 安装(转)
    Hbase 元数据一致性检查(转)
    Slow ReadProcessor&amp;Error Slow BlockReceiver错误日志分析(转)
    Hbase CMS GC 调优。
    [技术]排查线上问题
    crontab 误删恢复
    Hbase balancer RSgroup shell 脚本
    Hbase运维手册(1)
    Presto JVM.config
  • 原文地址:https://www.cnblogs.com/A-aron/p/10369228.html
Copyright © 2011-2022 走看看