基于Asp.Net Core 5.0依赖Quartz.Net框架编写的任务调度web管理平台
源码地址: https://github.com/246850/Calamus.TaskScheduler
演示地址:http://47.101.47.193:1063/

1、Quartz.NET框架核心类
IScheduler:调度者
IJobDetail:任务
ITrigger:触发器
JobKey:任务/触发器标识
JobDataMap:数据包
2、邮件通知(FluentEmail类库)
_fluentEmail.To(to).Subject(subject).Body(body, true).SendAsync();
3、Quartz.NET宿主方式,依靠IHostedService后台服务执行
internal class QuartzHostedService : IHostedService
{
private readonly ISchedulerFactory schedulerFactory;
private readonly IOptions<QuartzHostedServiceOptions> options;
private IScheduler scheduler = null!; public QuartzHostedService(
ISchedulerFactory schedulerFactory,
IOptions<QuartzHostedServiceOptions> options)
{
this.schedulerFactory = schedulerFactory;
this.options = options;
} public async Task StartAsync(CancellationToken cancellationToken)
{
scheduler = await schedulerFactory.GetScheduler(cancellationToken);
await scheduler.Start(cancellationToken);
} public Task StopAsync(CancellationToken cancellationToken)
{
return scheduler.Shutdown(options.Value.WaitForJobsToComplete, cancellationToken);
}
}
4.Asp.Net Core 5.0集成
安装依赖包
Quartz
Quartz.AspNetCore
Quartz.Plugins.TimeZoneConverter
Quartz.Serialization.Json
FluentEmail.Core
FluentEmail.Smtp
Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
options.Filters.Add<GatewayResultFilterAttribute>(); // 通用执行结果包装处理过滤器
options.Filters.Add<GlobalExceptionFilterAttribute>(); // 全局异常过滤器
})
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new DateTimeConverter()); // 日期格式化
})
.AddFluentValidation(config => // 请求模型参数验证
{
config.RunDefaultMvcValidationAfterFluentValidationExecutes = true; // false : 禁止默认模型验证
config.ValidatorOptions.CascadeMode = CascadeMode.Stop; // 不级联验证,第一个规则错误就停止
config.RegisterValidatorsFromAssemblyContaining<JobCreateOrUpdateValidator>();
});
services.AddHostedService<NLogHostService>(); // NLog 关闭服务
services.AddDistributedMemoryCache(); // 分布式缓存接口
services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));// 解决中文乱码
services.AddHttpClient(); // IHttpClientFactory IConfigurationSection quartzConfiguration = Configuration.GetSection("Quartz"); // Quartz配置节点 /***********Quartz.NET*********/
services.AddTransient<HttpJob>(); // 注册job至容器,必须步骤
services.AddQuartz(config =>
{
config.UseTimeZoneConverter();
// 使用MicrosoftDependencyInjectionJobFactory工厂类从 容器 中创建job实例
config.UseMicrosoftDependencyInjectionJobFactory(options =>
{
options.AllowDefaultConstructor = false; // 禁止使用无参构建函数创建 job
options.CreateScope = false;
});
config.UseDefaultThreadPool(options =>
{
options.MaxConcurrency = 10; // 最大并发执行线程数
});
config.UsePersistentStore(options =>
{
options.UseProperties = false;
//options.UseBinarySerializer(); // 二进制序列化
options.UseJsonSerializer(); // json序列化
options.UseMySql(ado =>
{
ado.ConnectionString = quartzConfiguration["Database"];
ado.TablePrefix = quartzConfiguration["TablePrefix"]; // 默认值 QRTZ_
ado.ConnectionStringName = "Quartz.net";
});
}); // 监听器
config.AddSchedulerListener<DefaultSchedulerListener>();
config.AddJobListener<DefaultJobListener>();
config.AddTriggerListener<DefaultTriggerListener>(); // 启动NLog日志文件清除job
config.ScheduleJob<ClearNLogJob>(trigger =>
{
trigger.WithIdentity(NLogJobKey.NameKey, NLogJobKey.GroupKey).StartNow()
.WithCronSchedule("0 0 0 1/3 * ? ", cron => cron.WithMisfireHandlingInstructionFireAndProceed()); // 从每月1日开始,每3天执行一次
}, job =>
{
job.WithIdentity(NLogJobKey.NameKey, NLogJobKey.GroupKey)
.StoreDurably(false) // 是否持久化, 无关联触发器时是否移除,false:移除
.RequestRecovery() // 重启后是否恢复任务
.WithDescription("每3天清空NLog日志文件");
});
});
// IHostedService宿主启动 Quartz服务 services.AddSingleton<IHostedService, QuartzHostedService>()
services.AddQuartzServer(options =>
{
// when shutting down we want jobs to complete gracefully
options.WaitForJobsToComplete = true; // 等待任务执行完,再退出
}); /***********FluentEmail*********/
// 为了将邮件通知配置在job data上, 不使用自带的service注册方式
//services.AddFluentEmail(quartzConfiguration["Smtp:UserName"], "Quartz.NET任务调度通知")
// .AddRazorRenderer()
// .AddSmtpSender(quartzConfiguration["Smtp:Host"], Convert.ToInt32(quartzConfiguration["Smtp:Port"]), quartzConfiguration["Smtp:UserName"], quartzConfiguration["Smtp:Password"]);
services.AddTransient<IFluentEmail>(serviceProvider =>
{
IScheduler scheduler = serviceProvider.GetRequiredService<ISchedulerFactory>().GetScheduler().Result; JobKey key = new JobKey(EmailJobKeys.NameKey, EmailJobKeys.GroupKey);
if (!scheduler.CheckExists(key).Result)
{
JobDataMap dataMap = new JobDataMap();
dataMap.Put(EmailJobKeys.Host, "smtp.qq.com");
dataMap.Put(EmailJobKeys.Port, 587); // 465端口一直尝试不通过,奇怪
dataMap.Put(EmailJobKeys.UserName, "390915549@qq.com"); // 作者qq,欢迎骚扰
dataMap.Put(EmailJobKeys.Password, "cirxjtemuzxycagf");
dataMap.Put(EmailJobKeys.To, string.Empty); // 接收者邮件支持多个,以 ; 隔开
dataMap.Put(EmailJobKeys.NickName, "Quartz.NET任务调度通知");
dataMap.Put(EmailJobKeys.CacheExpiry, 30); // 默认30分钟内只通知一次
IJobDetail job = JobBuilder.Create<HttpJob>()
.StoreDurably(true)
.RequestRecovery()
.WithDescription("邮件通知配置Job,切勿删除")
.WithIdentity(key)
.UsingJobData(dataMap)
.Build();
scheduler.AddJob(job, true); // 初始化邮件通知配置
} IJobDetail emailJob = scheduler.GetJobDetail(key).Result;
IFluentEmail fluentEmail = new Email(new ReplaceRenderer(),
new SmtpSender(new SmtpClient(emailJob.JobDataMap.GetString(EmailJobKeys.Host), emailJob.JobDataMap.GetInt(EmailJobKeys.Port))
{
EnableSsl = true,
Credentials = new NetworkCredential(emailJob.JobDataMap.GetString(EmailJobKeys.UserName),
emailJob.JobDataMap.GetString(EmailJobKeys.Password))
}),
emailJob.JobDataMap.GetString(EmailJobKeys.UserName),
emailJob.JobDataMap.GetString(EmailJobKeys.NickName));
return fluentEmail;
}); IocEngine.Instance.Init(services); // 实在没办法才弄个静态容器获取service, 监听器里无法通过构造函数 注入 ISchedulerFactory, IFluentEmail, 猜测应该是循环引用了
}

5、谢谢观看,拜拜
基于Asp.Net Core 5.0依赖Quartz.Net框架编写的任务调度web管理平台的更多相关文章
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)
最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...
- [译]基于ASP.NET Core 3.0的ABP v0.21已发布
基于ASP.NET Core 3.0的ABP v0.21已发布 在微软发布仅仅一个小时后, 基于ASP.NET Core 3.0的ABP v0.21也紧跟着发布了. v0.21没有新功能.它只是升级到 ...
- Asp.Net Core 2.0 项目实战(3)NCMVC角色权限管理前端UI预览及下载
Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...
- 基于ASP.NET Core 3.0快速搭建Razor Pages Web应用
前言 虽然说学习新的开发框架是一项巨大的投资,但是作为一个开发人员,不断学习新的技术并快速上手是我们应该掌握的技能,甚至是一个.NET Framework开发人员,学习.NET Core 新框架可以更 ...
- 基于ASP.NET Core 6.0的整洁架构
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本节将介绍基于ASP.NET Core的整洁架构的设计理念,同时基于理论落地的代码 ...
- 打造静态分析器(二)基于Asp.Net Core 3.0的AspectCore组件检测
上一篇,我们打造了一个简单的分析器,但是我们实际使用分析器就是为了对项目做分析检测,增加一些非语法的自检的 比如Asp.Net Core 3.0的替换依赖注入检测 设计分析 我们创建一个默认的Asp. ...
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(2)
第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 为Domain Model添加约束 前一部分, 我们已经把数据库创建出来了. 那么我们先看看这个数据库 ...
- [译]ASP.NET Core 2.0 依赖注入
问题 如何使用 ASP.NET Core 服务容器进行依赖注入? 答案 创建一个服务 public interface IGreetingService { string Greet(string t ...
- 基于ASP.Net Core开发一套通用后台框架记录-(项目的搭建)
写在前面 本系列博客是本人在学习的过程中搭建学习的记录,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 前期我不会公开源码,我想是一点点敲代码,不然复制.粘贴那就没意思了. ...
随机推荐
- JavaSE21-网络编程
1.网络编程入门 1.1 网络编程概述 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共 ...
- Spring MVC或Spring Boot配置默认访问页面不生效?
相信在开发项目过程中,设置默认访问页面应该都用过.但是有时候设置了却不起作用.你知道是什么原因吗?今天就来说说我遇到的问题. 首先说说配置默认访问页面有哪几种方式. 1.tomcat配置默认访问页面 ...
- iframe高度自动随着子页面的高度变化而变化(不止要在iframe标签里加上this.height=this.contentWindow.document.body.scrollHeight)
最近使用iframe整合页面遇到一些难题,走了很多弯路才解决,借此记录一下: 1 <!-- 页面主体内容 --> 2 <div class="iframe-wrapper& ...
- python SQLAlchemy反射生成models
1.安装SQLAcodegen pip install sqlacodegen 2.使用sqlacodegen生成案列 sqlacodegen mysql://root:123456@127.0.0. ...
- 自动测试LeetCode用例方法
自动合并测试LeetCode解题方法 在leetcode.com上答题,Run Code或者Sumbmit通常要Spending一会,如果提交一次就Accepted那还好,如果反复Wrong Answ ...
- K-NN(最近邻分类算法 python
# algorithm:K-NN(最近邻分类算法)# author:Kermit.L# time: 2016-8-7 #======================================== ...
- C# 锁与死锁
什么是死锁: 所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进. 因此我们举个例子来描述,如果此时有一个线程A,按照先锁a再 ...
- Dubbo服务暴露源码解析②
目录 0.配置解析 1.开始export 2.组装URL 3.服务暴露 疑问解析 先放一张官网的服务暴露时序图,对我们梳理源码有很大的帮助.注:不论是暴露还是导出或者是其他翻译,都是描述expor ...
- springMVC搭建分布式框架
https://www.cnblogs.com/lr393993507/p/7652717.html https://www.cnblogs.com/Tpf386/p/10987931.html
- 简单web页面第一步---表单
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncod ...