在我们日常开发工作中,经常会运用到Quartz+Topshelf组件的组合来开发一些定时任务。那么在.Net Core下如何去使用呢?我自己尝试搭建了一个测试项目,过程中遇到了以下一些问题:

  • Quartz 配置文件及版本问题。我们知道Quartz有2个配置文件,quartz.config和quartz.job.xml。前者负责组件初始化配置,后者负责job和triggle的配置。刚开始我是直接把framework下的配置文件直接拿过来用的,启动直接报错。主要问题在quartz.config

    quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
    

    这一段上。原因Quartz最新版本已经将Plugin模块单独剥离出一个独立的DLL,这里的引用也要变化。需要Nuget上下载Quartz.Plugins组件,并将上一段改成

    quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins
    
  • DI问题。为了贴合.Net Core DI精神,我们也要来实现Console程序的DI功能。第一个问题是Job如何DI?首先我们需要自己去实现JobFactory

        public class NewJobFactory : IJobFactory
    {
    private readonly IServiceProvider _serviceProvider; public NewJobFactory(IServiceProvider serviceProvider)
    {
    _serviceProvider = serviceProvider;
    }
    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
    return _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob;
    } public void ReturnJob(IJob job)
    {
    var disposable = job as IDisposable;
    disposable?.Dispose();
    }
    }

      注入方式

    IServiceCollection services = new ServiceCollection();
    services.AddScoped<IJobFactory, NewJobFactory>();
    services.AddSingleton(service =>
    {
    var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
    scheduler.JobFactory = service.GetService<IJobFactory>();
    return scheduler;
    });
  • Console程序的配置文件获取以及注入问题。众所周知,.Net Core下建立的Console程序就是一块白板,什么都没有。配置文件我们还得自己去建一个.json文件。并且需要自己从Nuget上下载的组件包(见后面项目结构截图)。加载方式如下
  •         private IConfiguration ConfigureConfiguration()
    {
    //配置文件
    var builder = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    return builder.Build();
    }

      注入方式如下

                if (configuration != null)
    {
    //iconfiguration注入
    services.AddSingleton<IConfiguration>(configuration);
    } //自定义 option方式注入
    services.Configure<AppSetting>(configuration);

      这样就可以在后续的类代码中 直接通过DI方式获取IConfiguration对象或者你自己的Option对象了

  贴上完整代码。

  Program.cs

        static void Main(string[] args)
{
HostFactory.Run(x =>
{
x.Service<ServiceRunner>();
x.SetDescription("gt.dotnetcore.consolesample");
x.SetDisplayName("gt.dotnetcore.consolesample");
x.SetServiceName("gt.dotnetcore.consolesample"); x.StartAutomatically();
});
}

  ServiceRunner.cs 启动的核心

    public class ServiceRunner : ServiceControl
{
//private readonly IScheduler _scheduler; private IServiceProvider _serviceProvider;
public ServiceRunner()
{
var configurationRoot = ConfigureConfiguration();
_serviceProvider = ConfigureServices(configurationRoot);
} private IConfiguration ConfigureConfiguration()
{
//配置文件
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
return builder.Build();
}
private IServiceProvider ConfigureServices(IConfiguration configuration)
{
//依赖注入
IServiceCollection services = new ServiceCollection();
//后续需要使用log的话,这里需要注入
services.AddTransient<ILoggerFactory, LoggerFactory>();
services.AddTransient<ITest, TestBiz>();
services.AddScoped<IJobFactory, NewJobFactory>();
if (configuration != null)
{
//iconfiguration注入
services.AddSingleton<IConfiguration>(configuration);
} //自定义 option方式注入
services.Configure<AppSetting>(configuration);
//这里注意Job的注入方式,不要强制指定IJob实现方式!!
services.AddScoped<TestJob>();
services.AddScoped<Test2Job>();
services.AddSingleton(service =>
{
var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
scheduler.JobFactory = service.GetService<IJobFactory>();
return scheduler;
});
//构建容器
return services.BuildServiceProvider();
} public bool Start(HostControl hostControl)
{
var scheduler = _serviceProvider.GetService(typeof(IScheduler)) as IScheduler;
scheduler.Start();
return true;
} public bool Stop(HostControl hostControl)
{
var scheduler = _serviceProvider.GetService(typeof(IScheduler)) as IScheduler;
scheduler.Shutdown(true);
return true;
}
}

  Test2Job.cs

    public class Test2Job : IJob
{
private ITest _testService;
private AppSetting _appsetting;
private IConfiguration _configuration; public Test2Job(ITest testService, IOptionsMonitor<AppSetting> appSettingAccessor, IConfiguration configuration)
{
_testService = testService;
_appsetting = appSettingAccessor.CurrentValue;
_configuration = configuration;
}
public Task Execute(IJobExecutionContext context)
{
Console.WriteLine($"job2222222222222 started:{_appsetting.TestCN}");
var t = _testService.Dowork(1);
t.Wait();
Console.WriteLine($"job2222222222222 ended:{_configuration["TestCN"]}"); return Task.CompletedTask;
}
}

  

  项目结构截图

附项目源码 https://gitee.com/gt1987/gt.dotnetcore

Topshelf+Quartz在.Net Core框架下的实现的更多相关文章

  1. 分别在.NET Framework 与 .NET Core 框架下 编写Windows Service(windows服务程序)

    前言,为什么会分别在两个框架下编写Windows Service,是因为最近在做区块链这块,使用的是NEO(小蚁区块链)的相关技术,NEO使用的是.net core 2.1,业务上需要写两个程序,一个 ...

  2. .net core+topshelf+quartz创建windows定时任务服务

    .net core+topshelf+quartz创建windows定时任务服务 准备工作 创建.net core 控制台应用程序,这里不做过多介绍 添加TopShelf包:TopShelf: 添加Q ...

  3. 微服务框架下的思维变化-OSS.Core基础思路

    如今框架两字已经烂大街了,xx公司架构设计随处可见,不过大多看个热闹,这些框架如何来的,细节又是如何思考的,相互之间的隔离依据又是什么...相信很多朋友应该依然存在自己的疑惑,特别是越来越火热的微服务 ...

  4. Windows Forms和WPF在Net Core 3.0框架下并不会支持跨平台

    Windows Forms和WPF在Net Core 3.0框架下并不会支持跨平台 微软将WinForms和WPF带到.NET Core 3.0这一事实,相信大家都有所了解,这是否意味着它在Linux ...

  5. C# 6 与 .NET Core 1.0 高级编程 - 40 ASP.NET Core(下)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 40 章  ASP.NET Core(下)),不对的地方欢迎指出与交流. 章节出自<Professiona ...

  6. 一个Mini的ASP.NET Core框架的实现

    一.ASP.NET Core Mini 在2019年1月的微软技术(苏州)俱乐部成立大会上,蒋金楠老师(大内老A)分享了一个名为“ASP.NET Core框架揭秘”的课程,他用不到200行的代码实现了 ...

  7. 200行代码,7个对象——让你了解ASP.NET Core框架的本质

    2019年1月19日,微软技术(苏州)俱乐部成立,我受邀在成立大会上作了一个名为<ASP.NET Core框架揭秘>的分享.在此次分享中,我按照ASP.NET Core自身的运行原理和设计 ...

  8. Spring Security框架下Restful Token的验证方案

    项目使用Restful的规范,权限内容的访问,考虑使用Token验证的权限解决方案. 验证方案(简要概括): 首先,用户需要登陆,成功登陆后返回一个Token串: 然后用户访问有权限的内容时需要上传T ...

  9. Spring 框架下 (增 删 改 )基本操作

    //applicationContext.xml 配置文件 <?xml version="1.0" encoding="UTF-8"?><be ...

随机推荐

  1. linux 的vi/vim消除查找到的高亮字符串

    方法如下: 在Vi里面如果要搜索某个关键字,只要键入/xxx就可以了,比如,要搜索一个函数,就键入/snprintf 然后回车,一个文件中,所有出现这个字样的地方都会被高亮显示.按n键,就可以自动把光 ...

  2. 在window里面安装ubuntu子系统并安装图形化界面

    一.开启windows子系统 1. 在win10设置里面开启开发人员选项 (设置-->更新安全--> 开发者选项  )选择开启 2.在控制面板里面开启windows子系统 (启用或关闭wi ...

  3. 解决MybatisGenerator多次运行mapper生成重复内容

    MybatisGenerator插件是Mybatis官方提供的,这个插件存在一个固有的Bug,即当第一次生成了Mapper.xml之后,再次运行会导致Mapper.xml生成重复内容,而影响正常的运行 ...

  4. Hadoop 学习笔记之 Incompatible namespaceIDs问题

    Hadoop重新格式化后,仍然datanode启动失败,查看log: org.apache.hadoop.hdfs.server.datanode.DataNode: Java.io.IOExcept ...

  5. MongoDB 学习笔记之 group聚合

    group聚合: key: 分组字段 cond:过滤条件 reduce: curr是当前行 result是每组的结果集 initial : 组变量初始值 finalize: 统计一组后的回调函数 用g ...

  6. 刷新:重新发现.NET与未来

    微软在比尔·盖茨手中创立并崛起, 成为PC互联网时代的霸主,很多70,80后都有MVP Ediwang的体验: 当时的微软对我来说就是神的存在.因为我认识电脑到使用电脑的一切几乎都离不开这家伟大的公司 ...

  7. R-forestplot包| HR结果绘制森林图

    本文首发于“生信补给站”微信公众号,https://mp.weixin.qq.com/s/2W1W-8JKTM4S4nml3VF51w 更多关于R语言,ggplot2绘图,生信分析的内容,敬请关注小号 ...

  8. 阿里云服务器ecs + tomcat + 域名解析 部署web页面

    1.购买ecs:https://www.aliyun.com/product/ecs?spm=5176.12825654.eofdhaal5.2.3bf92c4aYOB7gL&aly_as=A ...

  9. MySQL索引的建立与实现

    一.索引介绍 1.MySQL中,所有的数据类型都可以被索引,索引包括普通索引,唯一性索引,全文索引,单列索引,多列索引和空间索引等. 2.额外的:我已知的自动创建索引的时机:创建主键,唯一,外键约束的 ...

  10. 再谈Transaction——MySQL事务处理分析

    MySQL 事务基础概念/Definition of Transaction 事务(Transaction)是访问和更新数据库的程序执行单元;事务中可能包含一个或多个 sql 语句,这些语句要么都执行 ...