在我们日常开发工作中,经常会运用到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. Navicat 设置自增长初始值

    设置主键自增初始值

  2. [ProblemSolving][Ubuntu][LyX] The selected document class ... requires external files that are not available...

    I installed LyX in my Ubuntu(version LTS 18.04), but I just can't make it work. Every time I open an ...

  3. 怎样实现给DEDE5.7的栏目增加栏目图片

    前两天用DEDE做二次开发的时候,遇到一个问题,领导让给每个栏目增加一个栏目图片的功能,网上找了些东西,结合自己实际做的时候的方法,下面详细描述下具体的实现方式(只测试了V5.7版本,对低版本是否适用 ...

  4. Spark 学习笔记之 aggregateByKey

    aggregateByKey: import org.apache.spark.SparkContext import org.apache.spark.rdd.RDD import org.apac ...

  5. Sublime Text 3 配置 Phpcs

    Phpcs 插件介绍 可以为 Sublime Text 编辑器提供代码格式检测的功能,使用以下工具(全部可选): PHP_CodeSniffer (phpcs) Linter (php -l) PHP ...

  6. Spring Boot 2.X(六):Spring Boot 集成Redis

    Redis 简介 什么是 Redis Redis 是目前使用的非常广泛的免费开源内存数据库,是一个高性能的 key-value 数据库. Redis 与其他 key-value 缓存(如 Memcac ...

  7. 【Visual Studio】关于vs 打开网站时报错 配置iis express失败 无法访问IIS元数据库...

    关于vs 打开网站时报错 配置iis express失败 无法访问IIS元数据库... 我安装了vs2015,一开始创建项目,网站都没问题,有一次突然打开项目时报错,瞬间懵逼,我啥都没干啊!!! 网上 ...

  8. 【JZOJ5264】化学

    Description Input Output Sample Input 3 10 1 2 10 Sample Output 5 Hint   题解: 这个题目通过30%部分分的提示,我们可以猜出这 ...

  9. Python从入门到精通视频(全60集) ☝☝☝

    Python从入门到精通视频(全60集) Python入门到精通 学习 教程 首先,课程的顺序需要调整:一和三主要是介绍学习和布置开发环境的,一介绍的是非VS开发,三介绍的是VS开发.VS2017现在 ...

  10. Get https://172.18.255.243:6443/api/v1/namespaces/kube-system/configmaps/kubelet-config-1.12: dial tcp 172.18.255.243:6443: i/o timeout

    问题描述 使用外网加入集群的时候报如下错误: Get https://172.18.255.243:6443/api/v1/namespaces/kube-system/configmaps/kube ...