或者每次都要手动的来启动软件,在我们平时项

作者: 编程  发布:2019-11-06

在我们一向项目中时时会遇上定期任务,比如准期同步数据,依期备份数据,准期总括数据等,依期职分我们都掌握使用Quartz.net,此连串写的也是Quartz,可是以前,大家先用其余方法做个大概的依期职务实行入门。

注:近期网络海人民广播电视台湾大学介绍Quartz.net的篇章,以致Quartz.net官方网址络的Tutorial都以1.0本子的,而以此连串在2.0版本对项目进展了一点都不小规模的更正,使得原来的大多例子都无法运营,故写此文。由于自家是边学边用,加之本事写作水平都有限,错误自然在所无免,望轻拍,小编将不许期更新完备此贴,希望能为索要的敌人提供支持。

咱们平日在有个别景观下要求软件具有一个机关施行有个别任务的效果与利益,可是又不指望直接开发银行软件,可能每一次都要手动的来运营软件,这个时候大家可能够思谋到windows服务了。

首先呢,大家今日谐和先写三个轻巧的按期循环职责,话非常少说,直接上代码:

1. 类别介绍

首先创造多少个windows服务项目(详细音讯请参阅:C#创立Windows Service(Windows 服务)功底教程

先是步:创立项目,新建四个类库:大家命名称叫TaskBase

     于今的系统,业务数据是进一层大,守旧的同台管理格局有的时候候已经不能够满意客商需要,依期后台服务这种异步数据管理方式则日渐被大家选择。相信我们在日常的劳作中也时时遇上数据同步,或是准期邮件,短信唤醒等急需,Quartz.net(官方网站 卡塔 尔(阿拉伯语:قطر‎能够很好知足对四个windows服务的管理及监察和控制,同期在保管支付不难的情事下不失灵活,是相当精美的学业调整框架。

    图片 1

其次部:增加二个浮泛基本功类BaseMonitor:

和此外半数以上开源项目风度翩翩律Quartz.net也暗含了别样多少个卓绝的开源项目:

在开创好的品种中式点心击“单击此处切换来代码视图”切换来代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TaskBase
{
    /// <summary>
    /// 监测基础抽象类
    /// </summary>
    public abstract class BaseMonitor
    {

        protected System.Threading.Thread _thread;
        /// <summary>
        /// 监控时间间隔(毫秒)
        /// </summary>
        public virtual int Interval { get; set; }

        public virtual string Name { get; set; }
        /// <summary>
        /// 监控器状态
        /// </summary>
        public virtual TaskState State { get; set; }
        public BaseMonitor(string name)
        {
            Name = name;
            _thread = new System.Threading.Thread(BaseRun);
            _thread.IsBackground = true;//获取或设置一个值,该值指示某个线程是否为后台线程
            _thread.Start();
            State = TaskState.运行;
        }
        private void BaseRun()
        {          
            while (State==TaskState.运行)
            {
                try
                {
                    Run();
                    System.Threading.Thread.Sleep(Interval);
                }
                catch (Exception ex)
                {
                    State = TaskState.异常;
                    PCore.Log.LogTextHelper.WriteErrorLog(this.GetType().Name + "监控出现错误,此监视器已暂停!", ex);
                }
            }
        }
        protected virtual void Run()
        { }
    }
}

主导   ----Common.Logging(通用日志接口卡塔 尔(英语:State of Qatar)

作者们任重(Ren Zhong卡塔 尔(阿拉伯语:قطر‎而道远关切一下八个方法:

(代码中PCore.Log.LogTextHelper.WriteErrorLog 是三个写文本日志的法子,可活动写个此情势。卡塔尔

         ----C5(泛型集结类卡塔尔国

  • OnStart – 控战胜务运行
  • OnStop – 调整伏务结束

 注:此依期任务基本功类 是用 System.Threading.Thread 达成,此中 TaskState为叁个枚举来表示职责的情状:

演示程序

  例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TaskBase
{
   public enum TaskState
    {
        未开始=0,
        运行=1,
        暂停=2,
        异常=3
    }
}

         ----log4net(日志记录-通用日志接口实现卡塔 尔(阿拉伯语:قطر‎

图片 2图片 3

其三部:加多一个一连BaseMonitor的TestMontior类,代码如下:

         ----topshelf(跨平台服务宿主程序卡塔 尔(英语:State of Qatar)

 1     public partial class Service1 : ServiceBase
 2     {
 3         public Service1()
 4         {
 5             InitializeComponent();
 6         }
 7 
 8         protected override void OnStart(string[] args)
 9         {
10             //todo:这里是服务启动所执行的代码
11         }
12 
13         protected override void OnStop()
14         {
15             //todo:这里是服务停止所执行的代码
16         }
17     }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TaskBase
{
   public class TestMontior:BaseMonitor
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name">检测器名称</param>
        public TestMontior(string name) : base(name)
        {
        }
        /// <summary>
        /// 监控时间间隔(毫秒)
        /// </summary>
        public override int Interval
        {
            get
            {
              return  GlobalConfig.TestMonitorInterval;
            }          
        }
        public override string Name
        {
            get
            {
                return base.Name;
            }

            set
            {
                base.Name = value;
            }
        }

        public override TaskState State
        {
            get
            {
                return base.State;
            }

            set
            {
                base.State = value;
            }
        }
        protected override void Run()
        {          
            PCore.Log.LogTextHelper.WriteLog("TestMontitor监测器正在监测");
        }
    }
}

  Quartz.net使用的许然而Apache License,商业友好,使用者能够改正源码用于开源或购销类型,只需包括许可及改良表达。

View Code

注:TestMontior 也等于大家的Job,代码中 GlobalConfig是自个儿定义的三个大局参数类:

2. Quartz.net支出思路

 下边大家可以写三个准期职分的功效了:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TaskBase
{
   public static class GlobalConfig
    {
        public static int TestMonitorInterval
        {
            get { return 100 * 10; }
        }

        public static List<BaseMonitor> Monitor = new List<BaseMonitor>();
    }
}

 

  

创办完毕今后正是那些样子:

  我们来打探下Quartz.net中常用的多少个概念:

 1      private void StartDoSomething()
 2         {
 3             System.Timers.Timer timer = new System.Timers.Timer(10000); //间隔10秒
 4             timer.AutoReset = true;
 5             timer.Enabled = false;  //执行一次
 6             timer.Elapsed += new ElapsedEventHandler(ExecutionCode);
 7             timer.Start();
 8         }
 9 
10         private void ExecutionCode(object source, System.Timers.ElapsedEventArgs e)
11         {
12             string dtNow = DateTime.Now.ToString("HH:mm");
13             if (dtNow == "12:00")
14             {
15                 File.WriteAllText("D:/ExecutionService.txt", "服务执行了一次任务", Encoding.UTF8);
16             }
17         }

图片 4

  Scheduler  ---------主调整程序 --------- Quartz主题

下一场在OnStart的措施中调用上边的StartDoSomething的艺术

定期职责的底蕴类库已经创立达成,上边咱们来看怎么接收它。

  Job        ---------作业  --------- 服务要做的(业务操作卡塔 尔(阿拉伯语:قطر‎

1         protected override void OnStart(string[] args)
2         {
3             StartDoSomething();
4         }    

 第四部:在WEB中使用:创造叁个WEB  MVC项目,援引TaskBase,然后在Global.asax中加多以下代码:

  Trigger     ---------触发器  --------- 服务实行基准(曾几何时实行操作卡塔尔

如上就能够算是多少个简单的准期施行职责的windows服务了,这里大家还足以接受Quartz.Net来落到实处更坚实有力的职务调节作用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace WebTaskTest
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);


           TaskBase.GlobalConfig.Monitor.Add(new TaskBase.TestMontior("测试监控器Test"));//注册定时任务


        }
    }
}

  Listener    ---------事件监听器  --------- 实践期事件(Job试行前后/ Scheduler运转终止暂停时应该做哪些,能够挂一些一定事件卡塔 尔(阿拉伯语:قطر‎

 

运营WEB站点,查看日志如下:

  了然了那些概念之后,我们就可以整合这一个概念并整合治理出开辟的笔触:

第一来介绍一下Quartz.Net那一个框架:

图片 5

  先选取SchedulerFactory构建叁个Scheduler,运维Scheduler,之后创设Job和Trigger,若有作业监听须要,在Listener上加多对应的管理程序,再将Job和Trigger关联后放入Scheduler

  简单介绍:Quartz.Net是四个开源的任务调整框架,特别强盛,能够透过轻便的配备支持大家依期具体的操作。相对于大家用的线程里面while(true卡塔尔国然后sleep来推行有个别操作,应该算的上是高档,大气,上等级次序了。如今流行版本是2.2,新的本子里面有些措施名产生了扭转,从后面包车型大巴版本用过来的人应当会有体会.这里自身利用最常用,也是最安定的艺术--Windows服务中间使用Quartz.net,何况应用陈设的方式来安装触发器。(以上内容摘自互联网卡塔尔国

可以看到生机勃勃分钟实施二次,因为大家在GlobalConfig.TestMonitorInterval设置的正是生机勃勃分钟。

3. Quartz.net的归纳利用

  轻便的知道正是它亦可帮大家准时的劳作,也正是机械钟能够叫大家起床同样。

上面大家看怎么样在windows server中什么运用:

               1. 新建贰个调控台程序,引用Quartz.dll和Common.Logging.dll

  最近新型的本子是Quartz.NET 2.2.3 世家能够在那处下载

创建一个WindowsServerTest类库,援用TaskBse,加多一个windows服务:

               2. 新建三个类,命名叫SampleJob,继承并落到实处接口Quartz.IJob         

 

using Quartz;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;

namespace WindowsServerTest
{
    partial class TestService : ServiceBase
    {
        public TestService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            try
            {
                // TODO: 在此处添加代码以启动服务。
                PCore.Log.LogTextHelper.WriteLog("OnStart:Test服务开始...");

               TaskBase.GlobalConfig.Monitor.Add(new TaskBase.TestMontior("测试监控器Test"));//注册监视器




            }
            catch (Exception ex)
            {
                PCore.Log.LogTextHelper.WriteErrorLog("出错了",ex);
            }
        }

        protected override void OnStop()
        {

            // TODO: 在此处添加代码以执行停止服务所需的关闭操作。
            PCore.Log.LogTextHelper.WriteLog("OnStop:Test服务结束...");
        }
        protected override void OnPause()
        {
            PCore.Log.LogTextHelper.WriteLog("OnPause:Test服务暂停...");
        }
        protected override void OnContinue()
        {
            PCore.Log.LogTextHelper.WriteLog("OnContinue:Test服务继续...");
        }
    }
}

图片 6图片 7View Code

  以后我们要求在刚刚创造的服务项目中引用如下文件:

关于windows服务的装置卸载可自动百度,再此相当少哔哔了。

public class SampleJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            File.AppendAllText("C:\Quartz.txt", "SampleJob Is Run");
            File.AppendAllText("C:\Quartz.txt", Environment.NewLine);  
        }
    }

    图片 8

设置好服务早前后相继,大家查阅下日志如下:

              3.在Program.cs的main方法中写如下代码后运营这些调控台会程序会意识已经SampleJob中的Execute方法已经实施

  在安插文件中写好温馨的布局(本例子演示按期访谈钦点网址卡塔 尔(英语:State of Qatar)

 图片 9

 

图片 10图片 11

 

图片 12图片 13View Code

 1 <?xml version="1.0"?>
 2 <configuration>
 3   <configSections>
 4     <sectionGroup name="JobList">
 5       <section name="Job" type="MyService1101.MyConfigHandler,MyService1101"/>
 6     </sectionGroup>
 7   </configSections>
 8   <startup>
 9     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
10   </startup>
11   <JobList>
12     <Job>   <!--这里是一个任务节点-->
13       <add key="Url" value="http://www.baidu.com" />  <!--需要访问的Url-->
14       <add key="Hour" value="10" />   <!--开始时间小时,注意:这里的小时为0-23,如果是1点的话就是1,而不是01-->
15       <add key="Minute" value="30"/>    <!--开始时间分钟,注意:同上0-59-->
16     </Job>
17   </JobList>
18 </configuration>

此节中大家简要做了八个定期任务,下章大家将张开Quartz.net职责框架的牵线。(源代码会跟随前面包车型客车例证意气风发并上传),请继续关怀之后章节。

  ISchedulerFactory  factory = new StdSchedulerFactory();
            IScheduler scheduler = factory.GetScheduler();
            scheduler.Start();
            IJobDetail job = JobBuilder.Create<SampleJob>().WithIdentity("SampleJob", "JobGroup1").Build();
            ITrigger trigger = TriggerBuilder.Create().StartNow().Build();
            scheduler.ScheduleJob(job, trigger);

View Code

 

4. 使用topshelf创建WINDOWS服务

 

      注:此部分张善友同学早就写过 (卡塔尔,此节为保证思路连贯,简要介绍并引述部分代码**  

  新建一个MyConfigHandler.cs类来读取自定义配置节点

  也会有的网络基友会疑问,以调控台程序充当劳动宿主还平昔不意思的,那时候轮到Topshelf出场了, 使用它能够很有利的创设跨平台服务寄主,而在调节和测量检验时直接以调节台的款型运转就能够,极其便利。 大家引进topshelf.dll及 log4net.dll(topshelf须要),将事先main中代码放到服务类里,把main方法成为Host创设

图片 14图片 15

             服务类代码:

 1 public class MyConfigHandler : IConfigurationSectionHandler
 2     {
 3         public MyConfigHandler()
 4         {
 5         }
 6 
 7         public object Create(object parent, object configContext, System.Xml.XmlNode section)
 8         {
 9             NameValueCollection configs;
10             NameValueSectionHandler baseHandler = new NameValueSectionHandler();
11             configs = (NameValueCollection)baseHandler.Create(parent, configContext, section);
12             return configs;
13         }
14     }

图片 16图片 17View Code

View Code

  public class SampleService
    {
        ISchedulerFactory factory;
        IScheduler scheduler;
        public void Start()
        {
            File.AppendAllText("C:\Quartz.txt", "SampleService Is Run");
            File.AppendAllText("C:\Quartz.txt", Environment.NewLine);
            factory = new StdSchedulerFactory();
            scheduler = factory.GetScheduler();
            scheduler.Start();
            IJobDetail job = JobBuilder.Create<SampleJob>().WithIdentity("SampleJob", "JobGroup1").Build();
            ITrigger trigger = TriggerBuilder.Create().StartNow().Build();          
            scheduler.ScheduleJob(job, trigger);
        }
        public void Stop()
        {
            scheduler.Clear();
            File.AppendAllText("C:\Quartz.txt", "SampleService Is Stop");
            File.AppendAllText("C:\Quartz.txt", Environment.NewLine);
        }
    }

 

 

  然后新建一个SystemScheduler类来创立调治程序

            校订后的Main代码

图片 18图片 19

图片 20图片 21View Code

 1     public class SystemScheduler
 2     {
 3         private SystemScheduler()
 4         {
 5         }
 6 
 7         public static SystemScheduler CreateInstance()
 8         {
 9             return new SystemScheduler();
10         }
11 
12         private IScheduler _scheduler;
13 
14         public void StartScheduler()
15         {
16             //这里读取配置文件中的任务开始时间
17             int hour = int.Parse(((NameValueCollection)ConfigurationSettings.GetConfig("JobList/Job"))["Hour"]);
18             int minute = int.Parse(((NameValueCollection)ConfigurationSettings.GetConfig("JobList/Job"))["Minute"]);
19 
20             ISchedulerFactory schedulerFactory = new StdSchedulerFactory();//内存调度
21             _scheduler = schedulerFactory.GetScheduler();
22 
23             //创建一个Job来执行特定的任务
24             IJobDetail synchronousData = new JobDetailImpl("SynchronousData", typeof(SynchronousData));
25             //创建并定义触发器的规则(每天执行一次时间为:时:分)
26             ITrigger trigger =
27                 TriggerBuilder.Create()
28                     .WithDailyTimeIntervalSchedule(
29                         a => a.WithIntervalInHours(24).OnEveryDay().StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(hour, minute))).Build();
30             //将创建好的任务和触发规则加入到Quartz中
31             _scheduler.ScheduleJob(synchronousData, trigger);
32             //开始
33             _scheduler.Start();
34         }
35 
36         public void StopScheduler()
37         {
38             _scheduler.Shutdown();
39         }
40     }
        static void Main(string[] args)
        {
            var host = HostFactory.New(x =>
            {
                x.EnableDashboard(); x.Service<SampleService>(s =>
{
    s.SetServiceName("SampleService"); s.ConstructUsing(name => new SampleService());
    s.WhenStarted(tc => { tc.Start(); });
    s.WhenStopped(tc => tc.Stop());
});
                x.RunAsLocalSystem();
                x.SetDescription("SampleService Description");
                x.SetDisplayName("SampleService");
                x.SetServiceName("SampleService");
            });
            host.Run();

        }

View Code

 

 

            编写翻译后,cmd进到exe所在目录,并实践"项目名.exe install/uninstall" 完成劳动的设置与卸载

  新建三个SynchronousData类,让其促成IJob接口来实现SystemScheduler中自定义的天职

 

图片 22图片 23

 1     public class SynchronousData : IJob
 2     {
 3         public void Execute(IJobExecutionContext context)
 4            {
 5             string Url = ((NameValueCollection)ConfigurationSettings.GetConfig("JobList/Job"))["Url"];
 6             WebClient wc = new WebClient();
 7             WebRequest wr = WebRequest.Create(new Uri(Url));
 8             using (StreamWriter sw = File.AppendText(@"d:SchedulerService.txt"))
 9             {
10                 sw.WriteLine("------------------" + "MyService服务在:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "     执行了一次任务" + "------------------");
11                 sw.Flush();
12             }
13         }
14     }

View Code

 

  最终在OnStart中增多对那个调节程序的使用

1         protected override void OnStart(string[] args)
2         {
3             SystemScheduler _systemScheduler = SystemScheduler.CreateInstance();
4             _systemScheduler.StartScheduler();
5         }   

 

  程序生成后大家能够经过指令安装它

图片 24

  安装到位后在劳务中会有一个新的劳动项

  图片 25

  程序运转过后会在D:盘生成一个SchedulerService.txt文件

  图片 26

 

  本程序源码:下载

图片 27

图片 28

本文由9159.com发布于编程,转载请注明出处:或者每次都要手动的来启动软件,在我们平时项

关键词: