工作中需要做个每天定时发邮件的功能,了解之后知道java里有做定时任务比较容易的方法,就是Quartz,在C#里叫Quartz.Net。

在写代码之前需要引用几个dll文件,分别是C5.dll、Common.Logging.dll和Quartz.dll;还有一个QuartzManager.cs文件,直接复制到项目中

QuartzManager.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. using Quartz;
  7. using Quartz.Impl;
  8. using Quartz.Impl.Triggers;
  9.  
  10. namespace Quartz
  11. {
  12. public static class QuartzManager
  13. {
  14. private static ISchedulerFactory sf = null;
  15. private static IScheduler sched = null;
  16.  
  17. static QuartzManager()
  18. {
  19. sf = new StdSchedulerFactory();
  20. sched = sf.GetScheduler();
  21. sched.Start();
  22. }
  23.  
  24. /// <summary>
  25. /// 添加Job 并且以定点的形式运行
  26. /// </summary>
  27. /// <typeparam name="T"></typeparam>
  28. /// <param name="JobName"></param>
  29. /// <param name="CronTime"></param>
  30. /// <param name="jobDataMap"></param>
  31. /// <returns></returns>
  32. public static DateTimeOffset AddJob<T>(string JobName, string CronTime, string jobData) where T : IJob
  33. {
  34. IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").UsingJobData("jobData", jobData).Build();
  35. ICronTrigger CronTrigger = new CronTriggerImpl(JobName + "_CronTrigger", JobName + "_TriggerGroup", CronTime);
  36. return sched.ScheduleJob(jobCheck, CronTrigger);
  37. }
  38.  
  39. /// <summary>
  40. /// 添加Job 并且以定点的形式运行
  41. /// </summary>
  42. /// <typeparam name="T"></typeparam>
  43. /// <param name="JobName"></param>
  44. /// <param name="CronTime"></param>
  45. /// <returns></returns>
  46. public static DateTimeOffset AddJob<T>(string JobName, string CronTime) where T : IJob
  47. {
  48. return AddJob<T>(JobName, CronTime, null);
  49. }
  50.  
  51. /// <summary>
  52. /// 添加Job 并且以周期的形式运行
  53. /// </summary>
  54. /// <typeparam name="T"></typeparam>
  55. /// <param name="JobName"></param>
  56. /// <param name="SimpleTime">毫秒数</param>
  57. /// <returns></returns>
  58. public static DateTimeOffset AddJob<T>(string JobName, int SimpleTime) where T : IJob
  59. {
  60. return AddJob<T>(JobName, DateTime.UtcNow.AddMilliseconds(), TimeSpan.FromMilliseconds(SimpleTime));
  61. }
  62.  
  63. /// <summary>
  64. /// 添加Job 并且以周期的形式运行
  65. /// </summary>
  66. /// <typeparam name="T"></typeparam>
  67. /// <param name="JobName"></param>
  68. /// <param name="SimpleTime">毫秒数</param>
  69. /// <returns></returns>
  70. public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime) where T : IJob
  71. {
  72. return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime));
  73. }
  74.  
  75. /// <summary>
  76. /// 添加Job 并且以周期的形式运行
  77. /// </summary>
  78. /// <typeparam name="T"></typeparam>
  79. /// <param name="JobName"></param>
  80. /// <param name="SimpleTime"></param>
  81. /// <returns></returns>
  82. public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime) where T : IJob
  83. {
  84. return AddJob<T>(JobName, StartTime, SimpleTime, new Dictionary<string, object>());
  85. }
  86.  
  87. /// <summary>
  88. /// 添加Job 并且以周期的形式运行
  89. /// </summary>
  90. /// <typeparam name="T"></typeparam>
  91. /// <param name="JobName"></param>
  92. /// <param name="StartTime"></param>
  93. /// <param name="SimpleTime">毫秒数</param>
  94. /// <param name="jobDataMap"></param>
  95. /// <returns></returns>
  96. public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, int SimpleTime, string MapKey, object MapValue) where T : IJob
  97. {
  98. Dictionary<string, object> map = new Dictionary<string, object>();
  99. map.Add(MapKey, MapValue);
  100. return AddJob<T>(JobName, StartTime, TimeSpan.FromMilliseconds(SimpleTime), map);
  101. }
  102.  
  103. /// <summary>
  104. /// 添加Job 并且以周期的形式运行
  105. /// </summary>
  106. /// <typeparam name="T"></typeparam>
  107. /// <param name="JobName"></param>
  108. /// <param name="StartTime"></param>
  109. /// <param name="SimpleTime"></param>
  110. /// <param name="jobDataMap"></param>
  111. /// <returns></returns>
  112. public static DateTimeOffset AddJob<T>(string JobName, DateTimeOffset StartTime, TimeSpan SimpleTime, Dictionary<string, object> map) where T : IJob
  113. {
  114. IJobDetail jobCheck = JobBuilder.Create<T>().WithIdentity(JobName, JobName + "_Group").Build();
  115. jobCheck.JobDataMap.PutAll(map);
  116. ISimpleTrigger triggerCheck = new SimpleTriggerImpl(JobName + "_SimpleTrigger", JobName + "_TriggerGroup",
  117. StartTime,
  118. null,
  119. SimpleTriggerImpl.RepeatIndefinitely,
  120. SimpleTime);
  121. return sched.ScheduleJob(jobCheck, triggerCheck);
  122. }
  123.  
  124. /// <summary>
  125. /// 修改触发器时间,需要job名,以及修改结果
  126. /// CronTriggerImpl类型触发器
  127. /// </summary>
  128. public static void UpdateTime(string jobName, string CronTime)
  129. {
  130. TriggerKey TKey = new TriggerKey(jobName + "_CronTrigger", jobName + "_TriggerGroup");
  131. CronTriggerImpl cti = sched.GetTrigger(TKey) as CronTriggerImpl;
  132. cti.CronExpression = new CronExpression(CronTime);
  133. sched.RescheduleJob(TKey, cti);
  134. }
  135.  
  136. /// <summary>
  137. /// 修改触发器时间,需要job名,以及修改结果
  138. /// SimpleTriggerImpl类型触发器
  139. /// </summary>
  140. /// <param name="jobName"></param>
  141. /// <param name="SimpleTime">分钟数</param>
  142. public static void UpdateTime(string jobName, int SimpleTime)
  143. {
  144. UpdateTime(jobName, TimeSpan.FromMinutes(SimpleTime));
  145. }
  146.  
  147. /// <summary>
  148. /// 修改触发器时间,需要job名,以及修改结果
  149. /// SimpleTriggerImpl类型触发器
  150. /// </summary>
  151. public static void UpdateTime(string jobName, TimeSpan SimpleTime)
  152. {
  153. TriggerKey TKey = new TriggerKey(jobName + "_SimpleTrigger", jobName + "_TriggerGroup");
  154. SimpleTriggerImpl sti = sched.GetTrigger(TKey) as SimpleTriggerImpl;
  155. sti.RepeatInterval = SimpleTime;
  156. sched.RescheduleJob(TKey, sti);
  157. }
  158.  
  159. /// <summary>
  160. /// 暂停所有Job
  161. /// 暂停功能Quartz提供有很多,以后可扩充
  162. /// </summary>
  163. public static void PauseAll()
  164. {
  165. sched.PauseAll();
  166. }
  167.  
  168. /// <summary>
  169. /// 恢复所有Job
  170. /// 恢复功能Quartz提供有很多,以后可扩充
  171. /// </summary>
  172. public static void ResumeAll()
  173. {
  174. sched.ResumeAll();
  175. }
  176.  
  177. /// <summary>
  178. /// 删除Job
  179. /// 删除功能Quartz提供有很多,以后可扩充
  180. /// </summary>
  181. /// <param name="JobName"></param>
  182. public static void DeleteJob(string JobName)
  183. {
  184. JobKey jk = new JobKey(JobName, JobName + "_Group");
  185. sched.DeleteJob(jk);
  186. }
  187.  
  188. /// <summary>
  189. /// 卸载定时器
  190. /// </summary>
  191. /// <param name="waitForJobsToComplete">是否等待job执行完成</param>
  192. public static void Shutdown(bool waitForJobsToComplete)
  193. {
  194. sched.Shutdown(waitForJobsToComplete);
  195. }
  196. }
  197. }

窗体界面上只有一个Button按钮,点击之后将当前Windows窗体关闭,而我的定时任务就是实现这个关闭。

.closeForm();关闭窗体方法在另写的一个stopjob.cs类文件调用 这个类需要继承IJob

  1. using Quartz;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6.  
  7. namespace winform状态栏
  8. {
  9. [PersistJobDataAfterExecution]
  10. [DisallowConcurrentExecution]
  11. public class stopjob : IJob
  12. {
  13. public void Execute(IJobExecutionContext context)
  14. {
  15. Program.form.closeForm();
  16. }
  17. }
  18. }

上面代码中,Program.form并不是开始创建的那个窗体,而是在Program类文件中创建的静态Form。为什么另创建一个静态Form?涉及到子线程关闭主线程问题

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows.Forms;
  5.  
  6. namespace winform状态栏
  7. {
  8. static class Program
  9. {
  10.  
  11. public static Form1 form;
  12. /// <summary>
  13. /// 应用程序的主入口点。
  14. /// </summary>
  15. [STAThread]
  16. static void Main()
  17. {
  18. Application.EnableVisualStyles();
  19. Application.SetCompatibleTextRenderingDefault(false);
  20. form = new Form1();
  21. Application.Run(form);
  22. }
  23. }
  24. }

Form.cs文件里引用Quartz(using Quartz;)

然后是关闭按钮(Button)的事件

  1. using Quartz;
  2. using System;
  3. using System.Text.RegularExpressions;
  4. using System.Windows.Forms;
  5.  
  6. namespace winform状态栏
  7. {
  8. public partial class Form1 : Form
  9. {
  10. public Form1()
  11. {
  12. InitializeComponent();
  13. }
  14. private void button_close(object sender, EventArgs e)
  15. {
  16. //cron表达式 参考 http://www.cnblogs.com/sunjie9606/archive/2012/03/15/2397626.html
  17. QuartzManager.AddJob<stopjob>("每隔5秒", "*/5 * * * * ?");//每隔5秒执行一次这个方法
  18. }
  19.  
  20. private delegate void CloseForm();//设计到多线程,子线程去控制主线程的控件,InvokeRequired值为true,用到定义委托,使得这个控制行为成为主线程的行为
  21.  
  22. public void closeForm()
  23. {
  24. if (this.InvokeRequired)
  25. {
  26. this.BeginInvoke(new CloseForm(closeForm));
  27. }
  28. else
  29. {
  30. this.Close();
  31. }
  32. }
  33. }
  34. }

关于执行stopjob的时间,我这里是用的每隔5秒执行一次,具体的解释在另一位博主那里有介绍

  1. 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,大家可以试试别的,这样关于线程的问题应该就可以避免,这也是我没有想到的问题

C# 定时任务的更多相关文章

  1. Java定时任务的常用实现

    Java的定时任务有以下几种常用的实现方式: 1)Timer 2)ScheduledThreadPoolExecutor 3)Spring中集成Cron Quartz 接下来依次介绍这几类具体实现的方 ...

  2. [转]Java实现定时任务的三种方法

    在应用里经常都有用到在后台跑定时任务的需求.举个例子,比如需要在服务后台跑一个定时任务来进行非实时计算,清除临时数据.文件等.在本文里,我会给大家介绍3种不同的实现方法: 普通thread实现 Tim ...

  3. 使用python crontab设置linux定时任务

    熟悉linux的朋友应该知道在linux中可以使用crontab设置定时任务.可以通过命令crontab -e编写任务.当然也可以直接写配置文件设置任务. 但是有时候希望通过脚本自动设置,比如我们应用 ...

  4. C#定时任务组件之FluentScheduler

    FluentScheduler是.NET开源处理定时任务组件 1.任务的创建注册 public static void TaskActionByMinutes(Action action, int c ...

  5. 浅谈 linux 例行性工作 crontab (linux定时任务)

    定时任务大家都挺说过,就好比你手机上的闹钟,到了指定的时候就会响起. 今天在对redis缓存进行定时储存时又操作了一把,发现一些细节,写的不好.大家就将就看吧, 首先 简单介绍一下linux 例行性工 ...

  6. SpringMVC中定时任务配置

    在项目中使用定时任务是常有的事,比如每天定时进行数据同步或者备份等等. 以前在从事C语言开发的时候,定时任务都是通过写个shell脚本,然后添加到linux定时任务中进行调度的. 现在使用Spring ...

  7. springboot(九):定时任务

    在我们的项目开发过程中,经常需要定时任务来帮助我们来做一些内容,springboot默认已经帮我们实行了,只需要添加相应的注解就可以实现 1.pom包配置 pom包里面只需要引入springboot ...

  8. 详解java定时任务

    在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面LZ就其原理.实例以及Timer缺陷三个方面来解析JavaTimer定时器. ...

  9. [JAVA]定时任务之-Quartz使用篇

    Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简单或为运行十个,百个, ...

  10. 【译】Spring 4 基于TaskScheduler实现定时任务(注解)

    前言 译文链接:http://websystique.com/spring/spring-job-scheduling-with-scheduled-enablescheduling-annotati ...

随机推荐

  1. 资源预加载preload和资源预读取prefetch简明学习

    前面的话 基于VUE的前端小站改造成SSR服务器端渲染后,HTML文档会自动使用preload和prefetch来预加载所需资源,本文将详细介绍preload和prefetch的使用 资源优先级 在介 ...

  2. Spring cloud zuul跨域(二)

    使用  CorsFilter  解决ajax跨域问题 直接在zuul的main下面,创建corsFilter就可以了. @SpringBootApplication @EnableZuulProxy ...

  3. win10子系统 (linux for windows)打造python, pytorch开发环境

    一.windows设置 0.启用windows子系统 控制面板--程序--启用或关闭windows功能--勾选适用于linux的Windows子系统 确定后会重启电脑 1.下载Ubuntu 在Micr ...

  4. CF802C Heidi and Library (hard)

    题目描述 你有一个容量为k的空书架,现在共有n个请求,每个请求给定一本书ai,如果你的书架里没有这本书,你就必须以ci的价格购买这本书放入书架.当然,你可以在任何时候丢掉书架里的某本书.请求出完成这n ...

  5. Spring Boot整合Elasticsearch

    Spring Boot整合Elasticsearch   Elasticsearch是一个全文搜索引擎,专门用于处理大型数据集.根据描述,自然而然使用它来存储和搜索应用程序日志.与Logstash和K ...

  6. Django中related_name作用

    相当于我们使用related代替了在通过一个对象查询出多个对象集合时,使用表名_set来获取 我先定义两个模型,一个是作者,一个是作者出版的书籍,算是一对多的类型. class Person(mode ...

  7. SQL SERVER 查询所有数据表名称和数据行数

    SELECT a.name, b.rows FROM sysobjects AS a INNER JOIN sysindexes AS b ON a.id = b.id WHERE ( a.type ...

  8. 盒模型的垂直居中css

    https://www.cnblogs.com/zhouhuan/p/vertical_center.html

  9. 内核空间内存申请函数kmalloc kzalloc vmalloc的区别

    我们都知道在用户空间动态申请内存用的函数是 malloc(),这个函数在各种操作系统上的使用是一致的,对应的用户空间内存释放函数是 free().注意:动态申请的内存使用完后必须要释放,否则会造成内存 ...

  10. 2018-2019-2 网络对抗技术 20165232 Exp2 后门原理与实践

    2018-2019-2 网络对抗技术 20165232 Exp2 后门原理与实践 1. 后门原理与实践实验说明及预备知识 一.实验说明 任务一:使用netcat获取主机操作Shell,cron启动 ( ...