• Quartz.Net+Microsoft.Extensions.Hosting创建服务


    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代码

    1. static async Task Main()
    2. {
    3. var baseDir = AppDomain.CurrentDomain.BaseDirectory;
    4. #region 注册DI注入
    5. var host = Host.CreateDefaultBuilder()
    6. .ConfigureHostConfiguration(configurationBuilder =>
    7. {
    8. //This is to do some basic host configuration and should only add 2 sources
    9. configurationBuilder.SetBasePath(baseDir);
    10. configurationBuilder.AddEnvironmentVariables(prefix: "ASPNETCORE_");
    11. #if DEBUG
    12. Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
    13. #endif
    14. })
    15. .ConfigureAppConfiguration((_context, _builder) =>
    16. {
    17. var env = _context.HostingEnvironment;
    18. _builder.AddJsonFile("appsettings.json", false, true)
    19. .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);
    20. })
    21. .ConfigureServices((context, _services) =>
    22. {
    23. ConfigureServices(context.Configuration, _services);
    24. })
    25. .ConfigureLogging(logging =>
    26. {
    27. logging.ClearProviders();
    28. 通过config文件实现
    29. //logging.SetMinimumLevel(LogLevel.Information);
    30. logging.AddLog4Net();
    31. })
    32. .UseWindowsService()
    33. .Build();
    34. await host.RunAsync();//启动主机
    35. }

    2.2 配置服务

    1. ///
    2. /// 配置服务
    3. ///
    4. ///
    5. ///
    6. private static void ConfigureServices(IConfiguration config, IServiceCollection services)
    7. {
    8. configuration = config;
    9. //var loglevel = configration.GetValue("Logging:LogLevel:System.Net.Http.HttpClient");
    10. //监控平台Api
    11. services.AddSingleton();
    12. ///自定义HttpMessageHandler
    13. services.AddScoped();
    14. // 拿到的httplient 是新的实例
    15. services.AddHttpClient("MonitorLogApi", client =>
    16. {
    17. var _WXKFBaseUrl = config.GetValue<string>("MonitorLogApi:MonitorLogApiBaseUrl");
    18. var WXKFBaseUrl = _WXKFBaseUrl ?? "https://status-test.gileadchina.cn/api/services/MonitorLog/";
    19. client.BaseAddress = new Uri(WXKFBaseUrl);
    20. //默认接收
    21. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    22. client.Timeout = TimeSpan.FromSeconds(100);//100秒超时
    23. })
    24. .ConfigurePrimaryHttpMessageHandler(_ =>
    25. {
    26. HttpClientHandler handler = new HttpClientHandler();
    27. handler.AllowAutoRedirect = true;
    28. return handler;
    29. })
    30. .SetHandlerLifetime(TimeSpan.FromHours(12))
    31. .AddHttpMessageHandler();
    32. #region Quartz.Net
    33. // base configuration from appsettings.json
    34. services.Configure(configuration.GetSection("Quartz"));
    35. services.AddQuartz(qz =>
    36. {
    37. // as of 3.3.2 this also injects scoped services (like EF DbContext) without problems
    38. qz.UseMicrosoftDependencyInjectionJobFactory();
    39. // or for scoped service support like EF Core DbContext
    40. // q.UseMicrosoftDependencyInjectionScopedJobFactory();
    41. // these are the defaults
    42. qz.UseSimpleTypeLoader();
    43. qz.UseInMemoryStore();
    44. qz.UseDefaultThreadPool(tp =>
    45. {
    46. tp.MaxConcurrency = 10;
    47. });
    48. //使用配置文件
    49. //qz.UseXmlSchedulingConfiguration(x => x.Files = new string[] {
    50. // "quartz_jobs.xml"
    51. //});
    52. #region 手动添加Job
    53. // qz.ScheduleJob(trigger =>
    54. // {
    55. // string time = System.Configuration.ConfigurationManager.AppSettings["AutoSendHospitalTopList2BusinessJobTriggerTime"].ToString();
    56. //#if DEBUG
    57. // time = "0 */1 * * * ?";//每分钟执行一次
    58. //#endif
    59. // trigger
    60. // .WithIdentity("发送进销存Dail报表,每time执行一次", "AutoSendHospitalTopList2BusinessJobGroup")
    61. // .WithCronSchedule(time)
    62. // .StartNow();
    63. // }, jobdtl =>
    64. // {
    65. // jobdtl.WithIdentity("AutoSendHospitalTopList2BusinessJob", "AutoSendHospitalTopList2BusinessJobGroup");
    66. // });
    67. // qz.ScheduleJob(trigger =>
    68. // {
    69. // string time = System.Configuration.ConfigurationManager.AppSettings["AutoSendSalesDailyReportJobTriggerTime"].ToString();
    70. //#if DEBUG
    71. // time = "0 */1 * * * ?";//每分钟执行一次
    72. //#endif
    73. // trigger
    74. // .WithIdentity("发送进销存Dail报表,每time执行一次", "AutoSendSalesDailyReportJobGroup")
    75. // .WithCronSchedule(time)
    76. // .StartNow();
    77. // }, jobdtl =>
    78. // {
    79. // jobdtl.WithIdentity("AutoSendSalesDailyReportJob", "AutoSendSalesDailyReportJobGroup");
    80. // });
    81. #endregion
    82. });
    83. services.AddQuartzHostedService(qz =>
    84. {
    85. // when shutting down we want jobs to complete gracefully
    86. qz.WaitForJobsToComplete = true;
    87. });
    88. services.AddScoped();
    89. //services.AddHostedService();
    90. #endregion
    91. }

    2.3 appsettings.json

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

    2.4 job配置文件

    1. <job-scheduling-data version="2.0" xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    2. <processing-directives>
    3. <overwrite-existing-data>trueoverwrite-existing-data>
    4. processing-directives>
    5. <schedule>
    6. <job>
    7. <name>List2BusinessJobname>
    8. <group>jGP_List2BusinessJobgroup>
    9. <description>定时发送 description>
    10. <job-type>MailJob.Jobs.List2BusinessJob, CODIReportJobjob-type>
    11. <durable>truedurable>
    12. <recover>falserecover>
    13. <job-data-map>
    14. <entry>
    15. <key>taskNamekey>
    16. <value>List2Businessvalue>
    17. entry>
    18. <entry>
    19. <key>taskNameCNkey>
    20. <value>定时发送 医院属性value>
    21. entry>
    22. job-data-map>
    23. job>
    24. <trigger>
    25. <cron>
    26. <name>Tr_List2BusinessJobname>
    27. <group>GP_List2BusinessJobgroup>
    28. <job-name>List2BusinessJobjob-name>
    29. <job-group>jGP_List2BusinessJobjob-group>
    30. <misfire-instruction>SmartPolicymisfire-instruction>
    31. <cron-expression>0 */1 * * * ?cron-expression>
    32. cron>
    33. trigger>
    34. schedule>
    35. job-scheduling-data>

    2.5 Job代码

    1. ///
    2. /// 定时发送
    3. /// PersistJobDataAfterExecution: 执行完Job后保存 JobDataMap 当中固定数据,以便任务在重复执行的时候具有相同的 JobDataMap
    4. /// DisallowConcurrentExecution:不能同时运行同一作业的多个实例
    5. ///
    6. [PersistJobDataAfterExecution, DisallowConcurrentExecution]
    7. public class List2BusinessJob : IJob
    8. {
    9. ILogger _logger;
    10. AutoSendSalesDailyReportJobTask _AutoSendJobTask;
    11. public List2BusinessJob(ILogger logger, AutoSendSalesDailyReportJobTask AutoSendJobTask)
    12. {
    13. _logger = logger;
    14. _AutoSendJobTask = AutoSendJobTask;
    15. }
    16. public async Task Execute(IJobExecutionContext context)
    17. {
    18. AutoSendSalesDailyReportJobTask.setLogger(_logger);
    19. context.JobDetail.JobDataMap.TryGetValue("taskName", out object _taskName);
    20. context.JobDetail.JobDataMap.TryGetValue("taskNameCN", out object _taskNameCN);
    21. ThreadContext.Properties["taskName"] = _taskName ?? "List2Business";
    22. LogicalThreadContext.Properties["taskName"] = _taskName ?? "List2Business";
    23. ThreadContext.Properties["taskNameCN"] = _taskNameCN ?? "定时发送Job";
    24. LogicalThreadContext.Properties["taskNameCN"] = _taskNameCN ?? "定时发送Job";
    25. try
    26. {
    27. _logger.LogInformation($"Start Execute:Job开始执行");
    28. //具体执行逻辑方法
    29. await _AutoSendJobTask.BeginTaskAsync("List");
    30. }
    31. catch (Exception ex)
    32. {
    33. _logger.LogError("Execute List2BusinessJob error:", ex.Message);
    34. }
    35. finally
    36. {
    37. _logger.LogInformation($"End Execute:Job执行结束");
    38. }
    39. }
    40. }

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

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

  • 相关阅读:
    qt学习之旅--QToolBar的使用(一)
    hadoop dfsadmin -refreshNodes 命令详解
    AJAX、Axios、JSON快速学习笔记(建议收藏)
    代码随想录 Day - 61|#503 下一个更大元素 II|#42 接雨水
    HTTP返回状态值详解整理
    数据在内存中的存储(2)
    【Spring Cloud】新闻头条微服务项目:自媒体前后端搭建&素材管理(含优化)
    【通信原理】通信系统概念、组成、分类、度量的分析与研究
    css实现div倾斜效果
    鸿蒙常用三方库地址一览
  • 原文地址:https://blog.csdn.net/foreverhot1019/article/details/127793074