1.首先准备Nuget包:

Microsoft.Extensions.Hosting.WindowsServices

Microsoft.Extensions.Logging.Log4Net.AspNetCore

Quartz.Extensions.Hosting

Quartz.Plugins

Microsoft.Extensions.Http.Polly 如果需要用HttpClient

2.上代码

2.1 main代码

static async Task Main()
{var baseDir = AppDomain.CurrentDomain.BaseDirectory;
#region 注册DI注入var host = Host.CreateDefaultBuilder().ConfigureHostConfiguration(configurationBuilder =>{//This is to do some basic host configuration and should only add 2 sourcesconfigurationBuilder.SetBasePath(baseDir);configurationBuilder.AddEnvironmentVariables(prefix: "ASPNETCORE_");
#if DEBUGEnvironment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
#endif}).ConfigureAppConfiguration((_context, _builder) =>{var env = _context.HostingEnvironment;_builder.AddJsonFile("appsettings.json", false, true).AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);}).ConfigureServices((context, _services) =>{ConfigureServices(context.Configuration, _services);}).ConfigureLogging(logging =>{logging.ClearProviders();通过config文件实现//logging.SetMinimumLevel(LogLevel.Information);logging.AddLog4Net();}).UseWindowsService().Build();await host.RunAsync();//启动主机
}

2.2 配置服务

/// <summary>/// 配置服务/// </summary>/// <param name="configuration"></param>/// <param name="services"></param>private static void ConfigureServices(IConfiguration config, IServiceCollection services){configuration = config;//var loglevel = configration.GetValue<string>("Logging:LogLevel:System.Net.Http.HttpClient");//监控平台Apiservices.AddSingleton<IMonitorLogApiService, MonitorLogApiService>();///自定义HttpMessageHandlerservices.AddScoped<LogErrorHttpMsgHandler>();//<IMonitorLogApiService, MonitorLogApiService> 拿到的httplient 是新的实例services.AddHttpClient("MonitorLogApi", client =>{var _WXKFBaseUrl = config.GetValue<string>("MonitorLogApi:MonitorLogApiBaseUrl");var WXKFBaseUrl = _WXKFBaseUrl ?? "https://status-test.gileadchina.cn/api/services/MonitorLog/";client.BaseAddress = new Uri(WXKFBaseUrl);//默认接收client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));client.Timeout = TimeSpan.FromSeconds(100);//100秒超时}).ConfigurePrimaryHttpMessageHandler(_ =>{HttpClientHandler handler = new HttpClientHandler();handler.AllowAutoRedirect = true;return handler;}).SetHandlerLifetime(TimeSpan.FromHours(12)).AddHttpMessageHandler<LogErrorHttpMsgHandler>();#region Quartz.Net// base configuration from appsettings.jsonservices.Configure<QuartzOptions>(configuration.GetSection("Quartz"));services.AddQuartz(qz =>{// as of 3.3.2 this also injects scoped services (like EF DbContext) without problemsqz.UseMicrosoftDependencyInjectionJobFactory();// or for scoped service support like EF Core DbContext// q.UseMicrosoftDependencyInjectionScopedJobFactory();// these are the defaultsqz.UseSimpleTypeLoader();qz.UseInMemoryStore();qz.UseDefaultThreadPool(tp =>{tp.MaxConcurrency = 10;});//使用配置文件//qz.UseXmlSchedulingConfiguration(x => x.Files = new string[] {//    "quartz_jobs.xml"//});#region 手动添加Job//                qz.ScheduleJob<HospitalTopList2BusinessJob>(trigger =>//                {//                    string time = System.Configuration.ConfigurationManager.AppSettings["AutoSendHospitalTopList2BusinessJobTriggerTime"].ToString();//#if DEBUG//                    time = "0 */1 * * * ?";//每分钟执行一次//#endif//                    trigger//                     .WithIdentity("发送进销存Dail报表,每time执行一次", "AutoSendHospitalTopList2BusinessJobGroup")//                     .WithCronSchedule(time)//                     .StartNow();//                }, jobdtl =>//                {//                    jobdtl.WithIdentity("AutoSendHospitalTopList2BusinessJob", "AutoSendHospitalTopList2BusinessJobGroup");//                });//                qz.ScheduleJob<AutoSendSalesDailyReportJob>(trigger =>//                {//                    string time = System.Configuration.ConfigurationManager.AppSettings["AutoSendSalesDailyReportJobTriggerTime"].ToString();//#if DEBUG//                    time = "0 */1 * * * ?";//每分钟执行一次//#endif//                    trigger//                     .WithIdentity("发送进销存Dail报表,每time执行一次", "AutoSendSalesDailyReportJobGroup")//                     .WithCronSchedule(time)//                     .StartNow();//                }, jobdtl =>//                {//                    jobdtl.WithIdentity("AutoSendSalesDailyReportJob", "AutoSendSalesDailyReportJobGroup");//                });#endregion});services.AddQuartzHostedService(qz =>{// when shutting down we want jobs to complete gracefullyqz.WaitForJobsToComplete = true;});services.AddScoped<AutoSendSalesDailyReportJobTask>();//services.AddHostedService<BackgroundJobService>();#endregion}

2.3 appsettings.json

{"Logging": {"LogLevel": {"Default": "Information", //Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5, and None = 6."Microsoft.AspNetCore": "Warning","System.Net.Http.HttpClient.*": "Warning" //httpclient日志等级//"System.Net.Http.HttpClient.MonitorLogApi.LogicalHandler": "Warning",//"System.Net.Http.HttpClient.MonitorLogApi.ClientHandler": "Warning"}},"MonitorLogApi": { //监控平台"MonitorLogApiBaseUrl": "https://aaa.cn/api/services/MonitorLog/"},"Quartz": {"schedName": "Report2Mail","quartz.scheduler.instanceId": "Report2MailScheduler","quartz.scheduler.instanceName": "Quartz Hosting Report Scheduler","quartz.threadPool.type": "Quartz Hosting Report Scheduler","quartz.threadPool.threadCount": 5,"quartz.threadPool.threadPriority": "Normal","quartz.jobStore.type": "Quartz.Simpl.RAMJobStore, Quartz","quartz.jobStore.misfireThreshold": 6000,"quartz.plugin.jobInitializer.type": "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins","quartz.plugin.jobInitializer.fileNames": "quartz_jobs.xml","quartz.plugin.jobInitializer.failOnFileNotFound": true}
}

2.4 job配置文件

<!-- This file contains job definitions in schema version 2.0 format -->
<job-scheduling-data version="2.0" xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><processing-directives><overwrite-existing-data>true</overwrite-existing-data></processing-directives><schedule><job><!--作业名称,同一个 group 中作业名称不能相同--><name>List2BusinessJob</name><!--作业分组名称,表示该作业所属分组--><group>jGP_List2BusinessJob</group><!--描述--><description>定时发送 </description><!--指定作业将调用的作业实现类,格式为:命名空间.类名,程序集名称--><job-type>MailJob.Jobs.List2BusinessJob, CODIReportJob</job-type><!--任务完成后是否依然保存到数据库,默认为false--><durable>true</durable><!--应用或服务重启之后是否忽略过期任务,默认为false--><recover>false</recover><!--传递给IJobExecutionContext 上下文数据--><job-data-map><entry><key>taskName</key><value>List2Business</value></entry><entry><key>taskNameCN</key><value>定时发送 医院属性</value></entry></job-data-map></job><trigger><!--复杂触发器,使用 cron-expression 设置触发器的行为 cron生成器:https://cron.qqe2.com/ --><cron><!--触发器名称,同一个 group 中作业名称不能相同--><name>Tr_List2BusinessJob</name><!--触发器分组名称,表示该触发器所属分组--><group>GP_List2BusinessJob</group><!--作业名,触发哪个作业,必须与 job 节点中的 group 相同--><job-name>List2BusinessJob</job-name><!--要调度的作业分组名称,必须与 job 节点中的 group 相同--><job-group>jGP_List2BusinessJob</job-group><!--开始作业的 utc 时间,北京时间需要+08:00,例如:<start-time>2017-12-01T08:00:00+08:00</start-time>,表示北京时间2017年12月1日上午8:00开始执行。注意:服务启动或重启时都会检测此属性。若没有设置此属性,服务会根据 cron-expression 的规则执行作业调度;若 start-time 的时间小于当前时间,服务启动后会忽略 cron-expression 的设置,立即执行一次调度,之后再根据 cron-expression 执行作业调度;若大于当前时间,服务会等到当前时间等于 start-time 的时间才开始执行,并根据 cron-expression 执行作业调度。如果没有特殊要求,可以忽略该属性。--><!--<start-time>2021-12-01T00:00:00+08:00</start-time>--><!--错过了触发 必须在 cron-expression 节点前DoNothing:不触发立即执行。等待下次Cron触发频率到达时刻开始按照Cron频率依次执行。即如果错过了某次执行,直接忽略。FireOnceNow:以当前时间为触发频率立刻触发一次执行,然后按照Cron频率依次执行。--><misfire-instruction>SmartPolicy</misfire-instruction><!--每1分钟执行一次--><cron-expression>0 */1 * * * ?</cron-expression></cron></trigger></schedule>
</job-scheduling-data>

2.5 Job代码

    /// <summary>/// 定时发送/// PersistJobDataAfterExecution: 执行完Job后保存 JobDataMap 当中固定数据,以便任务在重复执行的时候具有相同的 JobDataMap/// DisallowConcurrentExecution:不能同时运行同一作业的多个实例/// </summary>[PersistJobDataAfterExecution, DisallowConcurrentExecution]public class List2BusinessJob : IJob{ILogger<List2BusinessJob> _logger;AutoSendSalesDailyReportJobTask _AutoSendJobTask;public List2BusinessJob(ILogger<List2BusinessJob> logger, AutoSendSalesDailyReportJobTask AutoSendJobTask){_logger = logger;_AutoSendJobTask = AutoSendJobTask;}public async Task Execute(IJobExecutionContext context){AutoSendSalesDailyReportJobTask.setLogger(_logger);context.JobDetail.JobDataMap.TryGetValue("taskName", out object _taskName);context.JobDetail.JobDataMap.TryGetValue("taskNameCN", out object _taskNameCN);ThreadContext.Properties["taskName"] = _taskName ?? "List2Business";LogicalThreadContext.Properties["taskName"] = _taskName ?? "List2Business";ThreadContext.Properties["taskNameCN"] = _taskNameCN ?? "定时发送Job";LogicalThreadContext.Properties["taskNameCN"] = _taskNameCN ?? "定时发送Job";try{_logger.LogInformation($"Start Execute:Job开始执行");//具体执行逻辑方法await _AutoSendJobTask.BeginTaskAsync("List");}catch (Exception ex){_logger.LogError("Execute List2BusinessJob error:", ex.Message);}finally{_logger.LogInformation($"End Execute:Job执行结束");}}}

最后 通过 sc create reportjob binPath="exePath" 就可以创建服务了。

Microsoft.Extensions.Hosting 可以绑定 asp.net core 程序可以是framework 4.6.1 以后的任意应用程序,快速 创建 集 configuration、dependency injection、logging 的应用,自动管理应用 生命周期。

Quartz.Net+Microsoft.Extensions.Hosting创建服务相关推荐

  1. 使用.NET Core创建服务监视器应用程序

    目录 介绍 背景 数据库 .NET核心解决方案 ServiceMonitor.Core ServiceMonitor.Common 约定 观察者 ServiceMonitor.WebApi 仪表板 管 ...

  2. SpringBoot集成Quartz实现定时任务的动态创建、启动、暂停、恢复、删除。

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:毅大师 blog.csdn.net/qq_39648 ...

  3. 一起聊聊Microsoft.Extensions.DependencyInjection

    Microsoft.Extensions.DependencyInjection在github上同样是开源的,它在dotnetcore里被广泛的使用,比起之前的autofac,unity来说,它可以说 ...

  4. 使用微软依赖注入器Microsoft.Extensions.DependencyInjection

    目录 注册服务到容器 调用 ASP.NET Core MVC调用参考,构造函数注入 注册服务到容器 using Microsoft.Extensions.DependencyInjection; us ...

  5. 检测到包降级: Microsoft.Extensions.Configuration.Abstractions 从 2.1.1 降 2.1.0

    解决方法:工具-nuget管理包-程序管理控制台-选择 项目- 执行 -Install-Package Microsoft.Extensions.Configuration.Abstractions ...

  6. 用delphi创建服务程式

    视窗系统 2000/XP和2003等支持一种叫做"服务程式"的东西.程式作为服务启动有以下几个好处: (1)不用登陆进系统即可运行. (2)具有SYSTEM特权.所以你在进程管理器 ...

  7. SAP MM初阶创建服务采购订单时订购单位和物料组的缺省值

    SAP MM初阶创建服务采购订单时订购单位和物料组的缺省值 执行事务代码ME21N 创建采购订单,输入了单据类型,供应商,组织结构相关的数据,账户分配类别指定为K.如下图, 当把item catego ...

  8. SAP MM ML81N为采购订单创建服务接收单,报错- No matching PO items selected -

    SAP MM ML81N为采购订单创建服务接收单,报错- No matching PO items selected - SAP里的服务采购流程跟有形的实物采购流程并不相同.除了在采购单据上的差异以外 ...

  9. angular js一factory,service,provider创建服务

    服务:在AngularJS 中,服务是一个函数或对象 在写控制器的时候,不要复用controller,当我们的controller里面有相同的代码时,此时需要把它抽取成一个服务,所有的服务都符合依赖注 ...

最新文章

  1. python lambda 逻辑_Python之lambda表达式和内置函数
  2. mysql修改binlog格式_mysql binlog格式...
  3. 【Linux 内核 内存管理】内存管理架构 ① ( 内存管理架构组成 | 用户空间 | 内核空间 | MMU 硬件 | Linux 内核架构层次 | Linux 系统调用接口 )
  4. U3D包大小优化之microlib
  5. 使用pyinstaller打包python_使用pyinstaller打包Python项目,python
  6. Blazor+Dapr+K8s微服务之开发环境调试
  7. jrockit_Java堆空间– JRockit和IBM VM
  8. 福大软工1816 · 第一次团队作业
  9. Nacos实现环境隔离
  10. rk3399_android7.1添加个驱动且加上宏控编译
  11. flow time 是什么
  12. 算法:Find First and Last Position of Element in Sorted Array(在有序数组中搜索第一个和最后一个找到的数字)
  13. Python资源下载
  14. 全自动采集程序 php,快看CMS全自动采集影视程序
  15. 读《大数据思维与决策》的读后感
  16. ftp连不上linux虚拟机,cuteftp连不上Linux虚拟机的解决方案
  17. 小程序UI框架minui
  18. OkHttp3源码分析二 拦截器 上
  19. java练习题---前五章
  20. Android——Activity的生命周期

热门文章

  1. 产品经理--商业模式画布
  2. 完美Crack:Froala Editor 4.0.16 Patch
  3. System.Data.OleDb.OleDbException: 至少一个参数没有被指定值。
  4. Java大数据-Hadoop-HDFS客户端操作文件更名和移动
  5. 【STM32F407的DSP教程】第31章 STM32F407实数浮点FFT(支持单精度和双精度)
  6. CodeGear 6月8日西安新品发布会 笔记
  7. html文本需要在区块里面向上移动,HTML 区块
  8. Lua的string库函数列表
  9. size_t 到底是什么类型(有图有真相)
  10. 用C语言在NDS上编写程序