Microsoft.Extensions.Hosting.WindowsServices
Microsoft.Extensions.Logging.Log4Net.AspNetCore
Quartz.Extensions.Hosting
Quartz.Plugins
Microsoft.Extensions.Http.Polly 如果需要用HttpClient
- 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 sources
- configurationBuilder.SetBasePath(baseDir);
- configurationBuilder.AddEnvironmentVariables(prefix: "ASPNETCORE_");
- #if DEBUG
- Environment.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();//启动主机
- }
- ///
- /// 配置服务
- ///
- ///
- ///
- private static void ConfigureServices(IConfiguration config, IServiceCollection services)
- {
- configuration = config;
- //var loglevel = configration.GetValue
("Logging:LogLevel:System.Net.Http.HttpClient"); -
- //监控平台Api
- services.AddSingleton
(); - ///自定义HttpMessageHandler
- services.AddScoped
(); - //
拿到的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
(); -
- #region Quartz.Net
-
- // base configuration from appsettings.json
- services.Configure
(configuration.GetSection("Quartz")); - services.AddQuartz(qz =>
- {
- // as of 3.3.2 this also injects scoped services (like EF DbContext) without problems
- qz.UseMicrosoftDependencyInjectionJobFactory();
- // or for scoped service support like EF Core DbContext
- // q.UseMicrosoftDependencyInjectionScopedJobFactory();
- // these are the defaults
- qz.UseSimpleTypeLoader();
- qz.UseInMemoryStore();
- qz.UseDefaultThreadPool(tp =>
- {
- tp.MaxConcurrency = 10;
- });
- //使用配置文件
- //qz.UseXmlSchedulingConfiguration(x => x.Files = new string[] {
- // "quartz_jobs.xml"
- //});
- #region 手动添加Job
-
- // qz.ScheduleJob
(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
(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 gracefully
- qz.WaitForJobsToComplete = true;
- });
-
- services.AddScoped
(); - //services.AddHostedService
(); -
- #endregion
-
- }
- {
- "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
- }
- }
- <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>trueoverwrite-existing-data>
- processing-directives>
- <schedule>
- <job>
-
- <name>List2BusinessJobname>
-
- <group>jGP_List2BusinessJobgroup>
-
- <description>定时发送 description>
-
- <job-type>MailJob.Jobs.List2BusinessJob, CODIReportJobjob-type>
-
- <durable>truedurable>
-
- <recover>falserecover>
-
- <job-data-map>
- <entry>
- <key>taskNamekey>
- <value>List2Businessvalue>
- entry>
- <entry>
- <key>taskNameCNkey>
- <value>定时发送 医院属性value>
- entry>
- job-data-map>
- job>
- <trigger>
-
- <cron>
-
- <name>Tr_List2BusinessJobname>
-
- <group>GP_List2BusinessJobgroup>
-
- <job-name>List2BusinessJobjob-name>
-
- <job-group>jGP_List2BusinessJobjob-group>
-
-
-
- <misfire-instruction>SmartPolicymisfire-instruction>
-
- <cron-expression>0 */1 * * * ?cron-expression>
- cron>
- trigger>
- schedule>
- job-scheduling-data>
- ///
- /// 定时发送
- /// PersistJobDataAfterExecution: 执行完Job后保存 JobDataMap 当中固定数据,以便任务在重复执行的时候具有相同的 JobDataMap
- /// DisallowConcurrentExecution:不能同时运行同一作业的多个实例
- ///
- [PersistJobDataAfterExecution, DisallowConcurrentExecution]
- public class List2BusinessJob : IJob
- {
- ILogger
_logger; - AutoSendSalesDailyReportJobTask _AutoSendJobTask;
- public List2BusinessJob(ILogger
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 的应用,自动管理应用 生命周期。